OmniAICreator/Qiita-1.07M huggingface dataset:
VSCODEでDocker/Flaskまで構築する（Windows11）

### 本記事の背景
Dockerに関する記事が多くありますが、上記にピッタリのものがなかったので、あっちこっちから切り取ってまとめました。

### 本記事の前提条件
・Docker Desktop Windowsインストール済
・VSCODEインストール済
・VSCODE Docker拡張機能インストール済
・Flaskで簡単なアプリ構築済
・Git For Windowsインストール済
・Git Bashが使える
### 今回のWebアプリのファイルツリー
```terminal
2023/06/23  22:40               175 docker-compose.yml
2023/06/23  22:39               254 Dockerfile
2023/06/23  22:32               817 hello.py
2023/06/23  22:25             4,147 requirements.txt
```
### Dockerfile
Dockerコンテナをどのように構築するかの手順が書かれているファイル
今回はpythonライブラリーをpipコマンドでインストールする
つまり、Dockerコンテナの中に仮想環境を作っている
```Dockerfile
FROM python:3.10.2

WORKDIR /

ENV FLASK_APP=hello.py
ENV FLASK_RUN_HOST=0.0.0.0

COPY requirements.txt ./

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install -r requirements.txt

COPY . .
CMD ["flask","run"]
```
### Docker-compose.yml
これは、Dockerコンテナの中でサービスを定義し、実行するためのファイル
詳細は以下の記事に譲る
https://qiita.com/ryome/items/35df47a01a7fe3ac70ee
```yaml
version: '3.10'
services:
  python3:
    restart:  always
    build: .
    container_name: 'python3'
    working_dir: '/'
    tty: true
    ports:
      - "8005:5000"
```
### Dockerのイメージ作成
イメージ作成とは、Dockerコンテナをイメージを一個のCDを焼くみたいな感じです。
```terminal
docker build -t flask:v1.0 .
```
flask:イメージ名
v1.0：バージョン
作成後のイメージは以下に示す
```terminal
$ docker images
REPOSITORY             TAG       IMAGE ID       CREATED          SIZE
flask                  v1.0      d7a5ab9e6bea   40 minutes ago   2.46GB
python                 latest    09b1cac8826b   9 days ago       1.01GB
ubuntu                 latest    99284ca6cea0   2 weeks ago      77.8MB
```
### Dockerの起動、実行
```terminal
$ docker run --name flask2 -d docker-flask-python3:latest
acc71adb4f9f0c805e171f20f07598f0fcca137317f3276dea4375c71946e38c
```
--name:コンテナ名
-d: イメージ:TAG

VSCODE上で確認すると以下になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/645eee95-a1d6-eb75-bced-644b42e6f215.png)

### アプリケーションの確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/e0c4d91e-a50a-6e97-fc33-e91ea76c4e1a.png)

### Dockerの停止
```
docker-compose stop
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/7d0156d8-d0c4-7a17-a2db-94de55a88a15.png)

### アプリ更新する場合
```
docker-compose up --build
```
上記のコマンドが便利ですが、いろいろ副作用があるようです。

### 参考文献
https://qiita.com/tifa2chan/items/e9aa408244687a63a0ae
[AWS Q&A 365][ECS]AWSのよくある問題の毎日5選 #86

# 1. AWS FargateのAmazon ECSユーザーガイドにおけるリソースとは何ですか？
A: リソースとは、Amazon ECSで実行されるタスクに必要なCPUやメモリなどの計算リソースを指します。

# 2. Amazon ECSユーザーガイドのAWS Fargateでリソースをどのように管理しますか？
A: AWS FargateのAmazon ECSユーザーガイドでは、タスク定義の中でCPUとメモリの値を指定することによりリソースを管理します。

# 3. AWS FargateのAmazon ECSユーザーガイドにおけるタグとは何ですか？
A: タグは、クラスターやサービス、タスクなどのAmazon ECSリソースに割り当てることができるキーと値のペアです。これらはリソースの整理や検索に使用されます。

# 4. Amazon ECSリソースにタグを追加する方法は何ですか？
A: Amazon ECSリソースにタグを追加するには、AWS管理コンソール、AWS CLI、またはSDKを使用します。

# 5. AWS FargateのAmazon ECSユーザーガイドでタグを使用する目的は何ですか？
A: AWS FargateのAmazon ECSユーザーガイドでタグを使用する目的は、リソースの整理、コストの追跡、特定のリソースに対する権限の適用です。
[AWS Q&A 365][ECS]Daily Five Common Questions #86

# 1. What are resources in Amazon ECS User Guide for AWS Fargate? 
A: Resources refer to the computing resources such as CPU and memory required by tasks running in Amazon ECS. 

# 2. How can you manage resources in Amazon ECS User Guide for AWS Fargate? 
A: You can manage resources in Amazon ECS User Guide for AWS Fargate by specifying the CPU and memory values in the task definition. 

# 3. What are tags in Amazon ECS User Guide for AWS Fargate? 
A: Tags are key-value pairs that you can assign to Amazon ECS resources such as clusters, services, and tasks. They can be used for organizing and searching resources. 

# 4. How can you add tags to Amazon ECS resources? 
A: You can add tags to Amazon ECS resources using the AWS Management Console, AWS CLI, or SDKs. 

# 5. What is the purpose of using tags in Amazon ECS User Guide for AWS Fargate? 
A: The purpose of using tags in Amazon ECS User Guide for AWS Fargate is to organize resources, track costs, and apply permissions to specific resources.
【SwiftUI】contextMenuの形を変える方法

# はじめに
contextMenuの形を変える方法を紹介します。

# 作るもの
カプセル型のcontextMenuを作ります。
![スクリーンショット 2023-06-23 23.02.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2366249/90698abc-d508-2223-fe74-13ced6d88ae8.png)

# やり方
contentShapeの第一引数にcontextMenuPreviewを指定し、第二引数に好きな形を指定すると、contextMenuの形を変えることができます。

```swift
struct ContentView: View {
    var body: some View {
        Text("Hello, world!")
            .padding()
            .contentShape(.contextMenuPreview, Capsule())
            .contextMenu {
                Button("Button") {}
            }
    }
}
```

# まとめ
contentShapeを使うと、contextMenuの形を変えることができます。カプセルの他にも、円や四角形など、様々な形を指定できます。

# 参考文献
https://developer.apple.com/documentation/swiftui/view/contentshape(_:_:eofill:)

https://developer.apple.com/documentation/swiftui/contentshapekinds/contextmenupreview
Ubuntu 20.04 から 22.04 へのバージョンアップ

1. 現在のシステムを最新の状態にアップデート

    ```bash
    sudo apt update
    sudo apt upgrade
    sudo apt dist-upgrade
    ```
    
    `dist-upgrade` は、新しい依存関係を考慮に入れてパッケージをアップグレードするためのコマンド

2. システムのアップグレードが完了したら、不要なパッケージを削除

    ```bash
    sudo apt autoremove
    ```

3. Ubuntu の新しいリリースを検索するようにシステムに指示

    ```bash
    sudo do-release-upgrade -d
    ```

4. アップグレードが終了したら、システムを再起動

    ```bash
    sudo reboot
    ```

再起動後、Ubuntu 22.04が正しくインストールされていることを確認するには、再び `lsb_release -a` コマンドを実行します。これにより、新しいバージョン番号が表示されます。
Minimal BASH like line editing is supported. For the first word, TAB lists possible command completions. anywhere else TAB lists possible device or file completions.

Windows と Ubuntu のデュアルブートで起動時に以下のメッセージが出て困りました。

> Minimal BASH like line editing is supported. For the first word, TAB lists possible command completions. anywhere else TAB lists possible device or file completions.

# 対処

1. Ubuntu のライブ USB を起動順位 1 番にして起動
2. Try Ubuntu の一番上のオプションを選択して起動
3. ライブ環境が起動したらターミナルを開く
4. 次のコマンドを実行して、Ubuntu のインストールされているパーティションを探す
    ```
    sudo fdisk -l
    ```
    これにより、すべてのディスクとパーティションの一覧が表示される。Ubuntu がインストールされているパーティションを探す（"Linux" または "Linux filesystem" というラベルが付いている）。
5. Ubuntu がインストールされているパーティションをマウント（Ubuntuが `/dev/nvme0n1p4` にインストールされている場合の例）
    ```
    sudo mount /dev/nvme0n1p4 /mnt
    ```
6. chroot環境を設定
    ```
    sudo chroot /mnt
    ```
7. 以下のコマンドを実行して、GRUBを再インストール（特定のパーティションではなくディスク全体に `grub-install` とする）
    ```
    grub-install /dev/nvme0n1
    ```
8. GRUBの設定ファイルを更新
    ```
    update-grub
    ```

# grub-install 時のエラー

## cannot find a device for /boot/grub (is /dev mounted?)

1. `/mnt/boot/grub` ディレクトリが存在することを確認
    ```
    ls /mnt/boot/grub
    ```
    `grub.cfg` というファイルが表示されることを確認（ないとエラーの原因になる）

2. `/dev`, `/proc`, `/sys` ディレクトリを新しいルート環境にバインドマウント
    ```
    for i in /dev /dev/pts /proc /sys /run; do sudo mount -B $i /mnt$i; done
    ```

## cannot find EFI directory

EFIディレクトリは、通常、EFIシステムパーティション（ESP）と呼ばれる特別なパーティションに存在します。このパーティションには、UEFIファームウェアがシステムを起動するために必要なブートローダーが格納されています。

1. 以下のコマンドの出力から、EFI System というタイプのパーティションを探す
    ```
    sudo fdisk -l
    ```

2. 以下のコマンドを実行して、EFIシステムパーティションをマウント
    ```
    sudo mount /dev/nvme0n1p1 /mnt/boot/efi
    ```
Vimの基本操作について

### はじめに

vimの基本操作について学習したので、アウトプットしていきます。

### vimとは何か？

vimとは世界でも広く使われているテキストエディタの拡張版です。
コマンドを利用することで様々な操作を高速に実施することが可能です。
キーボードでほぼ全ての操作が可能。

### vimを学ぶ理由
あらゆるLinux系OSにおいてインストールされているエディタだから。
マウスを使わないので作業効率のアップが見込めるから。
vimを使いこなせるとなんかカッコ良さそうだから。（矢印キーを捨てる勇気をもとう！）

### モードについて
vimには複数のモードがあり、そのモードを適宜切り替えて操作を行う。

| モード　　 | 意味
|:--------: |:----------:|
normal(標準） |起動した時にみてるモード。移動、コピー
insert(挿入）|範囲を選択する時に使う。テキストの編集、追加、削除
visual（ビジュアル）|テキストの表示、選択
command　(コマンド）|各種コマンド（ファイルの保存やvimの終了）等が行える


### Vimの基本的なコマンド操作

#### カーソル移動（ノーマルモードでの）
| コマンド | 実行結果　　|
|:--------: |:----------:|
k          | 上に移動
j          | 下に移動
h          | 左に移動
l          | 右に移動
gg         | 一番上の行に移動する
G          | 一番下の行に移動する
W          |　次の単語の先頭に移動する
b          |　前の単語の先頭に移動する
e          |　単語の最後に移動する
0(数字のゼロ）|　行頭に移動する
$          | 行末に移動する



### ファイルを開く、保存・終了

| コマンド | 実行結果　　|
|:--------: |:----------:|
|vim       | vimを起動（開く）|
|vim +ファイル名| ファイルを指定して開く|
|:w        | 上書き保存
:w ファイル名　| 名前を付けて保存|
:q            | 終了　
:wq           | 保存して終了
:q!           | 保存せずに終了

### モードの切り替え
| コマンド | 実行結果　　|
|:--------: |:----------:|
| i        | 挿入（編集）モード
 esc       | ノーマルモード
:          | コマンドモード
v          | ビジュアルモード

### コピー＆ペースト
| コマンド | 実行結果　　|
|:--------: |:----------:|
| y         | 選択範囲のコピー
| yy        | 現在いる所にコピー
| 2yy       | 2行コピー(数を指定できる)
| P         | 現在いる所にペースト
| p         | 下にペースト
|.          | 直前の操作のリピート

### 削除
| コマンド | 実行結果　　|
|:--------: |:----------:|
| x         | 1文字削除
| dd        | 1行削除
| dw        | 単語の削除
| 2dd       | 2行削除(数を指定できる)
| u         | Undo(control +zと同じ役割）
| control+r | Undo redo(control + shift +zと同じ役割）

### 最後に
vimtutor（vimを学習できるもの）で初めてvimを学習した時はマウスを使わなくても、キーボードだけで移動できるんだ！と感動してしまいました。（笑）
vimのコマンドはもっと数多くのコマンドがあるので沢山触れて覚えていきたいと思います。
Google Cloud Secret ManagerとGitHub Actionsを連携させた環境変数の管理

- GitHub Actionsのワークフローを利用しているプロジェクトで、GCPのSecret Managerを使って環境変数を一元管理したいと思いました。しかし、GCPのSecret Managerから秘密情報を取得する際に「403 Permission Denied」エラーに遭遇しました。
- けっこう悩んだ末わかったのは、GCPの仕様として、自前で用意したサービスアカウントへSecret Managerへのアクセス権限を付与しても無効かもということでした。解決策として、デフォルトのサービスアカウントへ、自前のサービスアカウントを紐付けることで問題が解消しました。


## Google Cloudの認証の仕組み
今回は、GitHub Actionsの設定ファイル（Yaml）で、認証用JSONファイルを読み込むことでGoogle認証を行い、Secret Managerへ環境変数を適用する仕組みにしました。

```yaml
# 省略...

      - id: 'auth'
        name: 'Authenticate to Google Cloud'
        uses: 'google-github-actions/auth@v1'
        with:
          credentials_json: '${{ secrets.GCLOUD_CREDENTIAL }}'

# 省略...

      - name: Configure dotenv file
        # load envs from github secrets
        run: |
          cat << EOF > .env
          # 省略（環境変数の定義）...
          EOF
      - name: Run a new version of secrets
        run: |
          gcloud secrets versions add ${{ secrets.GCLOUD_SECRET_LABEL }} --data-file .env
```


そして認証ファイルで認証する自前のサービスアカウントには、PythonでGcloudのAPIを使うための権限（Secret Manager周りや、コンテナ管理のためのArtifact Registry周り、CloudStorageなど）を付与しておきました。


ちなみにPythonコードでは、ENVファイルの中身がGCPのSecret Managerから取得されます（下記、payload変数を作る箇所）

```Python
# 省略...

def get_google_secret_payload(secret_label, version) -> str | None:
    try:
        _, project_id = google.auth.default()
    except google.auth.exceptions.DefaultCredentialsError:
        project_id = None
    if project_id is None:
        return None

    # 省略...

    client = secretmanager.SecretManagerServiceClient()
    gcloud_secret_name = (
        f"projects/{project_id}/secrets/{secret_label}/versions/{version}"
    )
    payload = client.access_secret_version(name=gcloud_secret_name).payload.data.decode(
        "UTF-8"
    )
    return payload

# 省略...
```

# 問題の原因
これを動かした結果、エラー「google.api_core.exceptions.PermissionDenied: 403 Permission 'secretmanager.versions.access' denied for resource 'projects/***project/secrets/env_file/versions/latest' (or it may not exist)."」が発生して、Secret Managerから秘密情報を取得できず、、Secret Manager周りの権限を管理者権限にしても、同じでした。

その原因は、コードが動くCloudRun環境（今回私はCloudRunへのデプロイを行いました）がデフォルトで別のサービスアカウント（サービスアカウント「***-compute@developer.gserviceaccount.com」）を使用して認証するようになっているようであり、そのアカウントがSecret Managerへの適切なアクセス権限を持っていなかったためです。

# 解決策
デフォルトのサービスアカウントに「Secret Managerのシークレットアクセサー」ロールを付与し、

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521810/066d6718-c493-8da9-0942-e98bab1c13e6.png)


さらに自前のサービスアカウントにデフォルトのサービスアカウントユーザーへのアクセス権限を付与。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521810/46a28df0-9c84-f25c-7196-f576eea62749.png)

これにより、デフォルトのサービスアカウントを介してカスタムサービスアカウントの権限でSecret Managerにアクセスすることが可能になりました。バンザイ
【SwiftUI】背景に置く図形を指定する

# はじめに
背景色を設定して丸角にしたい時にcorner Round()を使用して丸角にしていました。
しかし、もっと簡単にbackgroundを丸角にできることを知ったので記録しておきます。

https://twitter.com/rowaido/status/1672154211386273793?s=46

# 実装
```swift: ❌

VStack { ... }
   .background(Color.red)
   .cornerRadius(10)
```

```swift: ✅
VStack { ... }
   .background(.red, in: RoundedRectangle(cornerRadius: 10))
```

# おわり
コードの行数が減っていい感じになりました。
AWS EventBridge AppFlowの実行レポートを取得するJSONパターン

# JSONパターン

```json
{
  "source": ["aws.appflow"],
  "detail-type": ["AppFlow End Flow Run Report"],
  "detail": {
    "flow-name": [{
      "prefix": "lambda-catch-flow"
    }]
  }
}
```

# 当該イベントをlambdaｄで取得して出力

```
2023-06-23T12:24:02.359Z	xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx	INFO	{
  version: '0',
  id: 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy',
  'detail-type': 'AppFlow End Flow Run Report',
  source: 'aws.appflow',
  account: '000000000000',
  time: '2023-06-23T12:24:01Z',
  region: 'ap-northeast-1',
  resources: [ 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz' ],
  detail: {
    'flow-name': 'lambda-catch-flow',
    'created-by': 'arn:aws:iam::000000000000:user/shun_okawa',
    'flow-arn': 'arn:aws:appflow:ap-northeast-1:000000000000:flow/lambda-catch-flow',
    source: 'S3',
    destination: 'S3',
    'source-object': 's3://miriwo-appflow-test/in',
    'destination-object': 's3://miriwo-appflow-test/out',
    'trigger-type': 'ONDEMAND',
    'num-of-records-processed': '4',
    'execution-id': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa',
    'num-of-records-filtered': '0',
    'start-time': '2023-06-23T12:23:53.893Z[UTC]',
    'num-of-documents-processed': '0',
    'end-time': '2023-06-23T12:24:01.628Z[UTC]',
    'num-of-record-failures': '0',
    'data-processed': '1032',
    status: 'Execution Successful'
  }
}

```
react + dndkit overflwでスクロールバーをつけると、要素の下に隠れてしまうを解決 

## 導入
overflow:scrollを付与して、スクロールバーを追加したときに、
ドラッグした要素が、要素の下に隠れてしまいました。

上記事象がなかなか解決できなかったので、解決策をまとめます。

使用技術は、

dndkit 
react

です。

## 結論
結論は、「DragOverRay」を使用することです。

DragOverRayは、dndkitに標準で用意されているコンポーネントです。

上記を使用することで、
overflowされたコンポーネントの中で、ドラッグしたとき要素の下に隠れてしまう現象を回避できます。

## DragOverRay
DragOverRayについては下記の公式リファレンスにまとめらています。
https://docs.dndkit.com/api-documentation/draggable/drag-overlay

下記引用です。しっかりスクロールがついてる場合は、使用を推薦すると書いてますね。

> If your draggable item is within a scrollable container, we also recommend you use a <DragOverlay>, otherwise you'll need to set the draggable element to position: fixed yourself so the item isn't restricted to the overflow and stacking context of its scroll container, and can move without being affected by the scroll position of its container. 

overflow時には、親要素を飛び越えてドラッグすると、別要素の下に隠れてしまうのは仕様のようですね。。

全くそのことに気が付かず、解決にかなりの時間を使ってしまいました。

## まとめ
dndkitのようなライブラリを使う場合、詰まったらまず公式リファレンスを読むことですね。。

ツールを使用する中で、うまくいかないことは、
まずツールのオプションとかでサポートしてくれてたりします。

dndkitは、英語のまとめ記事はあるのですが、
日本語の記事はなかなかないので、そこもまた難しいとこです。

今回の記事が少しでも誰かの役に立てば幸いです。
OpenWrt Wake on LAN ホスト自動起動

# はじめに

::: note
### 初心者対応構成
- スクリプトでの自動設定
- UCIとLuCi及びWinSCPにて比較しながら作業がおススメ
:::

::: note
### [PowerShell](https://learn.microsoft.com/ja-jp/powershell/scripting/what-is-windows-powershell?view=powershell-7.4)で[SSHアクセス](https://openwrt.org/docs/guide-quick-start/sshadministration)

- [PowerShellの開始](https://learn.microsoft.com/ja-jp/powershell/scripting/windows-powershell/starting-windows-powershell?view=powershell-7.4) (キー入力)：`Win`+`x` > `a` > `はい`
※Windows7以降標準搭載

```sh
ssh root@192.168.1.1
```

<details><summary>ssh root@192.168.1.1のショートカット作成（デスクトップ）</summary>

```powershell:powershell
$DESKTOP = ([Environment]::GetFolderPath("Desktop") + "\192.168.1.1.lnk")
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$DESKTOP")
$Shortcut.TargetPath = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"
$Shortcut.Arguments = '-windowstyle hidden -ExecutionPolicy RemoteSigned "Start-Process ssh root@192.168.1.1"'
$Shortcut.IconLocation = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe,0"
$Shortcut.WorkingDirectory = "."
$Shortcut.Save()

```

- `強制的に貼り付け`
- `yes`

---

</details>

<details><summary>SSHログイン出来ない場合:exclamation:</summary>

known_hostsクリア
- `C:\Users\yourusername\.ssh\known_hosts` ※Windows隠しファイル
```powershell:powershell
Clear-Content .ssh\known_hosts -Force

```
---
OpenSSHのインストール
※Windows 10 Fall Creators Update(1709)以降標準搭載
- 機能の確認
```powershell:powershell
Get-WindowsCapability -Online | Where-Object Name -like 'OpenSSH*'

```
- 機能のインストール
```powershell:powershell
Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0

```
---

</details>

:::

## [Wake on LAN](https://openwrt.org/docs/guide-user/services/w_o_l/wol)
::: note
### 設定
便利！
```bash
# package
opkg update
opkg install luci-i18n-wol-ja
/etc/init.d/rpcd restart

```
- [netfilter match でコンピュータをウェイクアップする](https://github.com/mister-benjamin/etherwake-nfqueue-openwrt)
```bash
opkg update
opkg install etherwake-nfqueue

```
:::

## [ホスト自動起動](https://openwrt.org/docs/guide-user/advanced/auto_wake_on_lan)
::: note
※**再起動に失敗する**
※再起動しないから検証放棄・・・
### 初期設定
```bash
TARGET_SET=192.168.1.10    # 該当デバイスのIPアドレス
MAC_SET=00:00:00:00:00:00  # 該当デバイスのマックアドレス

```

### 設定
```bash
opkg update
opkg install etherwake
# auto_wol_script
wget --no-check-certificate -O /bin/autowol.sh https://raw.githubusercontent.com/site-u2023/auto_wol_script/main/autowol.sh
chmod +x /bin/autowol.sh
sed -i -e "s/192.168.1.1/${TARGET_SET}/g" /bin/autowol.sh
sed -i -e "s/00:00:00:00:00:00/${MAC_SET}/g" /bin/autowol.sh
# start up
cp /etc/rc.local /etc/rc.local.bak
sed -i -e "s/exit 0//g" /etc/rc.local
echo "/bin/autowol.sh" > /etc/rc.local 
echo "exit 0" >> /etc/rc.local 

```

- http://192.168.1.1/wol/
:::
cscの作法 その376

# 概要
cscの作法、調べてみた。
wpfやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/63e4d03f-60ef-6a10-3eaf-d5e9e3790dc2.png)

# サンプルコード
wpf0.xaml

```
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Hello, WPF!">
</Window>


```

wpf0.cs

```

using System;
using System.IO;
using System.Windows;
using System.Windows.Markup;

namespace App
{
	public class Program {
		[STAThread]
		public static void Main() {
			Application app = new Application();
			Window win = null;
			using(FileStream fs = new FileStream("wpf0.xaml", FileMode.Open, FileAccess.Read))
			{
				win = (Window) XamlReader.Load(fs);
			}
			win.Show();
			app.Run(win);
		}
	}
}
```

# コンパイル手順

```
>set PATH=C:\Windows\Microsoft.NET\Framework\v4.0.30319;%PATH%


>csc /r:WPF\PresentationCore.dll;WPF\PresentationFramework.dll;WPF\WindowsBase.dll;System.Xaml.dll win0.cs


```

以上。
【ServiceNow】Utahリリース「フロー優先度」

# はじめに

みなさんこんにちは、三井情報株式会社です。
今回はUtahへのバージョンアップで新規追加された「フロー優先度」についてご紹介致します。

https://docs.servicenow.com/ja-JP/bundle/utah-build-workflows/page/administer/flow-designer/task/show-flow-priority-field.html

# フロー優先度とは

フロー優先度とは実行を待機している他のフローと比較し、優先度の低いフローを実行する前に優先度の高いフローを実行する機能です。本記事ではその設定方法について解説致します。

# 事前準備

フロー優先度はデフォルトでは非表示のため、事前準備が必要になります。

①フィルタナビゲータから下記を検索します。
 All > Process Automation > Flow Administration > Settings

![FlowPrioritySettings.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/1c1688a6-2947-f366-5afc-41ad827ac367.png)

➁いずれかのレコードを開き、フォーム上部の三本線から下記を選択します。
Configure > Form Layout

![FlowPriorityFormLayout.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/b199bc1e-5d88-7237-98a4-33d47b2002c1.png)

# フロー優先度の設定

一覧に戻り、歯車ボタンを押下して「Flow Priority」が一覧に表示されるようにします。

![FlowPriorityPersonalizeListColumns.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/0ed5fed6-4055-abd4-4f1e-4a6fae2a9f61.png)

設定したいレコードを開き、フロー優先度を設定します。

![FlowPrioritySet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/28c89180-e2a7-60f7-8b28-2dc5d069bb40.png)

既存のフローに関しては全て「Medium」に設定されています。

![FlowPriorityList.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/8d6de849-517c-fd93-77b1-8615c56c7972.png)

# おわりに

今回はUtahへのバージョンアップで新規追加された「フロー優先度」についてご紹介させていただきました。
最後まで読んでいただき、ありがとうございました。
オレ的Gemfileの見やすい記述方法

# はじめに

突然ですが皆さん！
Gemfieってどんな感じで書いてますか？？

プロジェクトによって様々だと思いますが、僕の経験上あまり整備されてない事も多くないファイルかなと思います:frowning2:

なので今回は僕が個人開発する際のGemfileの書き方をまとめてみようと思ったので、
特に勉強中の方や駆け出しの方に参考にしていただければと思いマンモス:elephant:

:::note
こんな書き方もあるんだ、へぇーくらいでみてもらえればと思います！
:::


# 2つのポイント

## 1.環境や役割ごとに見やすくする

Gemは特定の環境のみで使用する事があります。

```ruby:Gemfile
group :development do
  # 入れるGem
end

group :development, :test do
  # 入れるGem
end
```

実際こんな感じで書かれてるんじゃないかなと思います。

これぐらいシンプルだとそこまで問題ないのですが、Gemが増えてくると結構見にくくなってきます:sweat:

そこで僕なりに見やすく書いて見ると

```ruby:Gemfile
# ==========================================================
# 開発環境とテスト環境
# ==========================================================
group :development, :test do
  # 入れるGem
end

# ==========================================================
# 開発環境のみ
# ==========================================================
group :development do
  # 入れるGem
end
```

このように
```ruby:Gemfile
# ==========================================================
# グループ名
# ==========================================================
```

でまとめてやると見やすくなります！

環境以外にも僕は

```ruby:Gemfile
# ==========================================================
# デフォルトで入ってたもの
# ==========================================================

# ==========================================================
# 認証系
# ==========================================================

# ==========================================================
# 検索系
# ==========================================================
```

など、Gemの種類などでもグループ分けしています！

Gemをただ羅列して書くよりは上記のように書いてあげることによって、グッと見やすくなるかと思います:clap:

## 情報を書く

例えば、認証系のdeviseというGemを導入するとしましょう。

その際に単純に

```ruby:Gemfile
gem "devise"
```

とするだけではなんのGemか分かりづらいですよね？？

僕がGemを入れる際には以下の感じで情報をコメントで書いています:smiley:

```ruby:Gemfile
# ==========================================================
# 認証系
# ==========================================================

# GitHub https://github.com/heartcombo/devise
# RubyGems https://rubygems.org/gems/devise/versions/3.5.1?locale=ja
# 参考記事 あれば書く
gem "devise" # ログイン認証機能(軽く説明を書く)
```

GitHubのURLとRubyGemsのURLはどちらかでも良いとは思います！

個人的には

- [x] 公式ドキュメントの情報を書く
- [x] 導入や設定の際に見た参考記事を残しておく
- [x] ぱっと見でなんとなくなんのGemか分かるようなメモを残しておく

を意識しています:grin:

行数増えるの嫌な方もいると思いますが、僕は時間が経つと結構どんなGemなのかとか、なんで入れたんだろう的な事が多々起こるのでコメントを残しておく派です。

# まとめ

適当に追加してたり、ただ羅列して書くだけの人が割と多い印象だったので、今回僕なりのGemfileの書き方を紹介しました:grinning:

ControllerやModelと違ってコメントの量によってコードの可読性が下がると言ったデメリットが少ない、むしろちゃんとコメント残しておいた方が良いファイルだと僕は思います。

良ければぜひ参考にしてもらって、個人開発やプロジェクトで取り入れてもらえれば嬉しいです:blush:
「世の中」を知ってやりたいことが増えた話

先日弊社のメンバーが翔泳社様主催の若手のエンジニアが登壇するイベントに参加しました。

https://codezine.connpass.com/event/285100/

私はそれを視聴していたのですが、そのイベントの中で別の方がスピーチされていた内容が自身の考えともリンクしており共感を受けたので、その経験を記事にしたいと思います。

https://twitter.com/codezine/status/1671465591771914240?s=46&t=6RyW0gwt1c6OtfbiEoG8MA

## 「Web技術者養成プロジェクト」への参加
入社してから6年間ほど主に開発業務に携わっていました。頼れる先輩や上司のもとで色々業務について学ぶことで身についたスキルもたくさんあります。
そのような中で「Web技術者養成プロジェクト」のメンバー募集が始まりました。

このプロジェクトについてですが、弊社が開発に用いている技術はかなりレガシーであり、今後のことを考えると大きな問題となっていました。
その為、開発手法なども含めアップデートが求められておりスタートしたプロジェクトです。

## 井の中の蛙
このプロジェクトに参加する前の自分は、今回発表の中であった「井の中の蛙」になりかけていました。
例えばですが、元々の部署では集中管理型のソース管理を用いていました。
それに対して
「そういう環境だし、やりづらい部分はあるけどしょうがないよな」と思うだけでした。
Gitについて知ってはいますが「自分は関係ないし」とキチンと学ぶこともしませんでした。

## 大海を知り世界が変わった
プロジェクトに入ってからは怒涛の「勉強」でした。世間一般で使われている技術は今まで自分が使っている技術よりはるかに違っていて、それは頭の中にある「常識」を塗り替えるものでした。
手作業でファイルをコピーしながら運んでシステム入れ替えしていたのが、ソースを直してプッシュすればデプロイされる環境になったのです。
しかも、まだまだ世の中には「技術」「考え」がたくさんあり、調べだしたらキリがない。
とにかく自分はまだ未熟だと痛感しました。

## 「試してみよう」「伝えよう」ができるエンジニアに
エンジニアは「便利になるために頑張る人」だと思っています。
そして「世の中で用いられているモノ」は今までたくさんの人がより便利な世界を追求した結果出来上がった「便利の結晶」だと思います。
自分はやりたい事の一つに、***世の中に溢れている「便利」を社内に展開して、便利さを実感して欲しい***ということが加わりました。
今後もこの気持ちは忘れずにキャリアを積んでいけたらと思っています。
seleniumで「どの程度まで読み込みを待つか」を設定する

# 結論
ドライバのオプションに`pageLoadStrategy`を設定することで「どの程度まで読み込みを待つか」を設定できます。

# 解説
seleniumでは指定のページにアクセスしたときに「どの程度まで読み込みを待つか(読み込み戦略)」を設定することができます。以下に例を示します。
```normalの場合.py
# webdriverのimportや他のoptionのコードは割愛
# すべてのリソースをダウンロードするのを待つ
options.set_capability('pageLoadStrategy', 'normal')

with webdriver.Chrome("chromedriver", options = options) as driver:
    # 全てのリソースがダウンロードされるまでは処理が進まない
    driver.get('https://www.yahoo.co.jp/')
    # completeが出力される
    print(driver.execute_script('return document.readyState'))
```

`pageLoadStrategy`には以下の戦略を設定できます。

|戦略|内容|
|-|-|
|normal|すべてのリソースがダウンロードされるのを待つ(デフォルト)|
|eager|DOMにはアクセスできる状態まで待つ|
|none|ページの読み込みについて一切待たない|

「DOMにはアクセスできる状態まで待つ」というのは、`find_element`で要素を取得できる状態という認識でいいかと思います。

```eagerの場合.py
# webdriverのimportや他のoptionのコードは割愛
# DOMにはアクセスできる状態まで待つ
options.set_capability('pageLoadStrategy', 'eager')

with webdriver.Chrome("chromedriver", options = options) as driver:
    # DOMにはアクセスできる状態までは処理が進まない
    # リソースや通信状況によるが、'normal'より処理時間が早い
    driver.get('https://www.yahoo.co.jp/')
    # interactiveが出力される
    print(driver.execute_script('return document.readyState'))
    # page_sourceの内容からも、DOMにアクセスできそうなことが分かる
    print(driver.page_source)
```

```noneの場合.py
# webdriverのimportや他のoptionのコードは割愛
# ページの読み込みについて一切待たない
options.set_capability('pageLoadStrategy', 'none')

with webdriver.Chrome("chromedriver", options = options) as driver:
    driver.set_network_conditions(
        latency = 10000, # 10秒遅延させる
        download_throughput = 500 * 1024,
        upload_throughput = 500 * 1024 #download_throughput, upload_throughputは引数に渡す必要がある。
    )
    # 上のコードで遅延を発生させているが読み込みは一切待たない
    driver.get('https://www.yahoo.co.jp/')
    # loadingなどが出力される
    print(driver.execute_script('return document.readyState'))
    # 何も表示されないことが多い
    print(driver.page_source)
```

# 注意事項

下記の記事を一部引用します。

https://www.selenium.dev/ja/documentation/webdriver/drivers/options/

> URL 経由で新しいページに移動する場合、デフォルトでは、WebDriver は、ドキュメントの準備完了状態が完了するまで、 ナビゲーション メソッド (driver.navigate().get() など) の完了を保留します。 これは必ずしもページの読み込みが完了したことを意味するわけではありません。 特に、Ready State が完了した後に JavaScript を使用してコンテンツを動的に読み込むシングル ページ アプリケーションのようなサイトの場合はそうです。

私自身も完全に理解できていない点、ご了承ください。javascriptの`document.readyState`を確認しているようです。このステータスと「読み込み完了」が必ずしも一致するものではないから、「normal」でも読み込めていないということがあるという意味なのでしょうか・・・？申し訳ないですが、ここは私もよくわかってません。ただ、javascriptで通信して動的な挙動をするwebページでは`pageLoadStrategy`だけでページの読み込み状況を信頼し切るのは注意したほうが良さそうです。

以上です。

# 参考
https://www.selenium.dev/ja/documentation/webdriver/drivers/options/

https://qiita.com/wearemusiclover/items/3fd2b42480df25cc614d
結局すべては期待値調整だよ！というお話。

この記事は[Qiita Engineer Festa 2023](https://qiita.com/official-campaigns/engineer-festa/2023) 参加記事です。
　
### この記事で書くこと

周囲と協調して、より良い仕事をするためにどんなことを考えて仕事をしているかについて、私個人の考え方をできるだけ簡単な言葉で書こうと思います。
　
### この記事で書かないこと

学術的な根拠などはありません。
この考え方を強制するものでも、他の考え方を否定するものではありません。

## 【はじめに】こんな風に思ったことはありませんか？

* 上司・部下・他部署の人は何も理解してくれない！！
* こんな当たり前のことも分からないの？
* あ〜、あの時本当に失敗した〜。いつまで経っても後悔してる・・・。
* 自分はなんてダメな存在なんだ・・・。

## それ、期待値調整で解決できます！（たぶん）

### CASE1：上司・部下・他部署の人は何も理解してくれない！！

この場合、期待値は下記になっていると思います。

```期待値
（自分が相手に対して感じている）相手だったらこう理解してくれるはず！　　＞　　（実際の相手から見た）理解の状況
```

自分自身から見て相手に対する期待値が上回っている状況です。
「理解してくれるはず！」「理解するべきだ！」と思っていても何も事態は好転しません。
相手と対話することによって期待値をすり合わせていきましょう。

### CASE2：こんな当たり前のことも分からないの？

この場合、期待値は下記になっていると思います。

```期待値
（自分が思っている）当たり前のレベル　　＞　　（周囲が思っている）当たり前のレベル
```

自分自身の考える当たり前のレベルが周囲のそれを上回っている状況です。
「こんな当たり前のこともできないなんて！」「こいつは何も分かってない！」と蔑んでも何も事態は好転しません。
周囲と当たり前のレベルを定義することによって期待値をすり合わせていきましょう。

### CASE3：あ〜、あの時本当に失敗した〜。いつまで経っても後悔してる・・・。

この場合、期待値は下記になっていると思います。

```期待値
（過去の自分ができたであろうと考える）結果　　＞　　（過去の自分が実際にできた）結果
```

自分自身の考える「できたであろう結果」が実際の結果を上回っている状況です。
「自分はもっとできたはず！」「本当はもっと成果が出せたはず！」と自責思考で考えられるのは素晴らしいですが、過度な自責思考は自分を苦しめ続けます。
過去の結果は事実として受け止めて、その期待値のギャップを元に内省し、今後に向けた教科書にしていきましょう。


### CASE4：自分はなんてダメな存在なんだ・・・。

この場合、期待値は下記になっていると思います。

```期待値
（自分が思う）自分の能力　　＞　　（実際の自分が持っている）能力
```

自分が自分に期待している能力や期待が実際の能力を上回っている状況です。
「自分はもっとできる！」と上昇志向を持つのは素晴らしいですが、過度にストレッチした「こうあるべきの自分」は自分を苦しめ続けます。
過度に自分へのプレッシャーはかけずに、ちょっとストレッチした期待値を持っていると気持ちよく成長していくことができると思います。


## まとめ

自分と周囲、自分と自分、それぞれの期待値を見つめてすり合わせて行くことができると人生は好転する気がします。
先日、チーム内の話で紹介した本があり、その本を改めて読み直す中で考え方をまとめてみようかな〜と思いました。

■この考えに至った本のご紹介
[うまくいっている人の考え方 完全版](https://www.amazon.co.jp/dp/4799313282/)
[他者と働く──「わかりあえなさ」から始める組織論](https://www.amazon.co.jp/dp/B07Y5FF3M4/)
水曜どうでしょうに学ぶ最高のチームの作り方のお話

この記事は[Qiita Engineer Festa 2023](https://qiita.com/official-campaigns/engineer-festa/2023) 参加記事です。
　
### この記事で書くこと
**水曜どうでしょう愛**
　
### この記事で書かないこと
ためになる話
　
# はじめに

## 水曜どうでしょうとは
:::note info
　『水曜どうでしょう』は、北海道テレビ（HTB）制作のバラエティ深夜番組。
通称は「どうでしょう」・「水どう」・「どうリタ（リターンズ）」・「どうクラ（Classic）」など。
　シンボルキャラクターは福助人形。
　レギュラー放送が終了した2002年9月以降は、再放送の『どうでしょうリターンズ』・『水曜どうでしょうClassic』が全国各地で放送されており、2007年には全国47都道府県すべてで放送を達成した。
　現在も数年に1回のペースで『水曜どうでしょう』自体の新作が撮影・作成され、こちらも北海道での本放送開始を皮切りに順次放送されている。また、番組を再構成・再編集したDVD『水曜どうでしょうDVD全集』も発売されている。
:::
[Wikipedia](https://ja.wikipedia.org/wiki/%E6%B0%B4%E6%9B%9C%E3%81%A9%E3%81%86%E3%81%A7%E3%81%97%E3%82%87%E3%81%86)から引用

### もっと言い換えると・・・

* 大泉洋　（俳優 通称にょういずみにょう）
* 鈴井貴之（大泉の所属事務所会長/映画監督 通称ミスター）
* 藤村忠寿（チーフディレクター 通称ふじやん/魔神）
* 嬉野雅道（ディレクター兼カメラマン 通称うれしー）

の4人（通称どうでしょう班）による ~~旅番組である。~~ 移動の様子の垂れ流しを中心とする、 **人間の欲望・苦悩・絶望・堕落を観察するバラエティー番組** である。

※個人の感想です。褒めてます。

:::note alert
以降は、番組のネタバレが含まれます。
個人的にはネタバレしていても楽しめる番組だと考えていますが、ネタバレに抵抗がある方は **ハートマークとポケットマークだけ押してブラウザバック** してください。
:::


# 水曜どうでしょうに学ぶ最高のチームの作り方

実際の出来事と、そこからの学びを対比で羅列してみます。

## シェフ大泉　夏野菜スペシャル

### あったこと
料理を振る舞う企画と聞き、乗り気で参加したところ、
* 一度目は野菜づくりをさせられる
* 二度目は皿づくりをさせられる
* 三度目にようやく料理を作るも酷評される

一つの企画で２回も騙されボヤくが、なんだかんだ楽しみながら企画はしっかりやり通す。

### 学び
チームで仕事をする上で
* 自分の考えとは異なる状況や方針
* 不条理や不合理と **思える** 状況

は多くある。
その状態に対して愚痴や不満を吐き続けるのではなく、 **楽しみ方を模索しながらチームで取り組んでいく。**

## ジャングル・リベンジ

### あったこと
過去にマレーシアのジャングルで野生動物観察を行い、４人全員が二度と行きたくないと思ったにも関わらず、どうでしょう幹部（大泉以外）が、大泉が驚く姿を見たいがためだけに大泉を騙す再訪を企画し、 **4人全員で** 再度ジャングルに行く。

### 学び
グループではなくチームとして仕事をするために、
* やると決めたら **チームで取り組む**
* 誰かに負担を偏らせるのではなく、 **チーム全員が辛さも楽しさも同じ分ずつ分かち合う**
* **自由と責任** はセットであり、 **責任は個人ではなくチーム** で持つ

という気持ちを持って取り組む。

## 日本全国絵ハガキの旅2

### あったこと
全国の絵ハガキを取り寄せ、その束から引いた場所を探し、同じ構図で写真を撮っていくという企画で、早々に出発地である札幌の時計台を引いてしまうが、編集で最後に持ってくることはせずに、順番通りに旅を続けた。

### 学び
仕事をする上で、
* 手を抜きたくなること
* ちょっとズルをしたくなること

は意外とある。
それでも、 **うそをつかない、悪いことをしない** を大切にする。

## 対決列島_〜甘いもの国盗り物語〜

### あったこと
早食いに自信のある藤やんが、別の企画でしろくま（鹿児島名物）の早食いを行った際に、ミスターに負けたことをキッカケに、北海道から鹿児島全国の都道府県を回りながら、全国の名産の早食い勝負をしていく企画。
勝負の途中で、旅館の夕飯を美味しく食べたいという思いが湧いたことから、一県一県で勝負をするのではなく、関東大会・近畿大会と複数を取りまとめて勝負をすることにした。

### 学び
チームで活動する上で、優先度が変わることは多くある。
そんな時でも、
* チームで議論し **意思決定** を行う
  * **理想は全員の合意** を得て意思決定を行う
  * 意思決定後は、 **納得を自ら作り** に行く
* 目的はブラさないように **柔軟に対応** していく

ことが大切。

## 原付西日本制覇

### あったこと
京都を回る旅番組と大泉を騙したが、実際は原付のスーパーカブで京都から鹿児島へ向かうという企画。
大泉の疲労がピークに達し、演者側ではない藤やんが代打としてカブの運転を代わった。

### 学び
チームでゴールに向かう上で、不測の事態は必ずおこる。
そんな時も
* **役割や固定観念にとらわれず** に、常に最善策を考える
* 辛い人がいたら、 **チームでカバー** すること

を当たり前にしていく。

## ヨーロッパ20ヵ国完全制覇_完結編

### あったこと
入国ビザのいらないヨーロッパ20カ国をレンタカーで回るという企画を実施し、初回は回りきれず、2回目も回りきれず、3度目の正直として挑んだ企画。
ゴール地点をポルトガルにあるユーラシア大陸最西端のロカ岬と決めて挑んだが、最終的にロカ岬の位置が分からずロカ岬の手前にあるラソ岬をゴールとした。
しかし、実際はラソ岬でも無く、地獄の口という観光地であった。

### 学び（反面教師にしたい）
長期間に及ぶプロジェクトでは、ゴール直前が一番大切になる。
* ゴールを見誤らないこと
* ゴールまでの道筋をしっかり定めること
* ゴールまでの時間を逆算して行動すること

を大切にしたい。

# まとめ

水曜どうでしょうには、中毒性がありますので、用法用量をお守りください。
![image (30).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/394384/e144dd5d-30cd-c27c-40a2-c8e0f2d46390.png)



## 番組テーマソングから一節

>一人きりでは できない事も　
>タフな笑顔の 仲間となら乗りきれる

1/6の夢旅人2002／樋口了一

## 本当のまとめ
**水曜どうでしょう** は、すごく楽しめる番組です。
水曜どうでしょうと共に素敵なエンジニアライフをお送りください。
何者にもなれない私の生存戦略に関するお話。

この記事は[Qiita Engineer Festa 2023](https://qiita.com/official-campaigns/engineer-festa/2023) 参加記事です。
株式会社PE-BANKさんの[エンジニアキャリアについてあなたの考えをシェアしよう！](https://qiita.com/official-events/0d4c7ac216324bd6a3b9)キャンペーンへの参加記事になります。

### 記事の背景
文系出身ながら、新卒からエンジニアとしてキャリアをスタートし、十数年経ちました。
お世辞にも優秀とは言えない自分自身が、「こんなはずじゃなかった」という感情と向き合い、乗り越え、今はなんとかキャリアを形成しています。
そんな恥ずかしくもあるキャリアとの向き合い方を赤裸々にさらけ出すことで、キャリアに悩む「何者にもなれない誰か」の鬱蒼とした気持ちを軽くできるのではないか？と考え書いてみようと思いました。

### この記事で書くこと
「何者かになりたい」
そんな思いを持って社会人になった私の「何者にもなれない自分」との向き合い方や生存戦略（キャリアに対する考え方）について書いてみようと思います。
前半は、**キモい自分語り**です。
本題は、[こちら](https://qiita.com/pilot_fish/items/3069a1869c0d1e442490#%E6%9C%AC%E9%A1%8C%E4%BD%95%E8%80%85%E3%81%AB%E3%82%82%E3%81%AA%E3%82%8C%E3%81%AA%E3%81%84%E7%A7%81%E3%81%AE%E7%94%9F%E5%AD%98%E6%88%A6%E7%95%A5)まで読み飛ばしてください。

# 何者かになりたいと思っていたのに、何者にもなれなかった話。
## キャリアの概略
中小SIer→創業期スタートアップベンチャー→医療系事業会社→現職　の4社を経験しています。
（正確には、3社目が在籍中にホールディングス化し、子会社へ在籍出向もしていたので6社目になります。）
新卒時代からエンジニアを軸に仕事をしていますが、兼務としてバックオフィス部門の立ち上げ（人事・総務・経理）、営業、情シス、事業の責任者など、エンジニア以外の職種も経験しています。
つい先日、キャリアの棚卸しをしたので、興味があれば[こちら](https://pilot-fish.hatenablog.jp/entry/2023/01/31/0353)を御覧ください。

## 何者かになれると思っていた新卒時代
新卒で入った会社では、確か同期が15人位いました。
その中で文系出身は私一人。
新卒研修では同期に差をつけられまいと必死に食らいついていました。

実業務に入ってからは短期間の受託開発を数件経験したあと、お客様先へ常駐しての開発に入りました。
コテコテの関西弁のお客様からは「シバくぞ」と「飲み行くか？」しか言われた記憶が残ってないほど、いろいろ教えてもらったりかわいがってもらったりしました。
サブシステムの開発主担当を任せてもらったり、社会人としての自信やエンジニアとしての自信も付き始めた時、別の受託開発プロジェクトへの異動が決まりました。

## 何者にもなれないと感じた挫折挫折の日々
新しいプロジェクトは少数メンバーかつ周りは圧倒的強者の百戦錬磨のエンジニア。
「こんなはずじゃなかった」「もっとできるはずだ」と自分自身に対して絶望したり、過度のプレッシャーをかけたり気持ちの浮き沈みが激しかったです。

今思い返してみても、当時は「何者にもなれない」と思いながらも、それを認めることができずとにかくがむしゃらに走り続けていた気がします。

## 社会人人生で一番の苦境
そんながむしゃらに暗中模索で走り続けていた2社目の時、転機が訪れます。
初めての管理職での挫折、これまでの経験が全く活かせない現場、家庭内の問題が重なり、糸がプツンと切れてしまい走り続けることに疲れてしまった時期が来ました。
1ヶ月仕事を休ませてもらい、のんびりとした日々を過ごしました。

## 「何者にもなれない自分」を受け入れることで得た安堵
仕事というものから一定期間離れることで、「何か成し遂げられるはずだ」というプレッシャーを自分にかけることを抑え、「何者にもなれない自分」を等身大の自分として受け入れることができ、文字通り霧が晴れた爽快な気分になったことを覚えています。
そこからの社会人人生は割りと好転し、圧倒的ポジティブ思考で過ごすことができています。

# 【本題】何者にもなれない私の生存戦略

## 「何者かでありたい」という幻想を捨てる
「どうなりたいか？」を考えながら、そこへ向かって進んでいくことはとても大切です。
でも、身の丈にあった目標や努力で近づける目指したい姿にとどめ、現実離れした幻想は早く捨てることが必要だと考えています。
上には上がいます。
自身の位置から見た天上人になれる・ならなければ、という現実離れしすぎた過度なプレッシャーを自分に掛けることを捨てるのです。

まったく運動をしない私が、いきなりベンチプレス100kgをあげようとしたら怪我をします。
物事には順序がありますし、現状からみて到底無理なレベルで過度に自分に負荷を与えるのは自分を苦しめるだけです。

## 「何者でもない自分」「何者にもなれない自分」を素直に受け止める。
パレートの法則や2:6:2の法則でも言うところの中位や下位だったとしても、ありのままの自分をそのまま受け入れるのです。
生きてるだけですごいんです。普通のことを普通にできるだけでもすごいんです。

まったく運動をしない私が、ベンチプレス1kg（そもそも1kgってあるの？ってレベル）をあげられたら、それだけですごいんです。
まず、現状を理解するために動き出せたことがすごいんです。
100kgあげられないから、自分はもうダメだなんて思う必要はありません。

## 今、この瞬間「何者であるべきか？」を考えて動く
上には上がいます。
言葉は悪いですが、言い換えれば下には下がいます。

なんでもかんでもできるスーパーマンなんてそうそう存在しません。
愛と勇気だけが友達のあのヒーローだって、頭を作ってくれる人や届けてくれいる人がいなければ水をかけられて終わりです。

人は得意・不得意があり、世の中は役割分担でできているんです。
しかも、その得意・不得意は所属するコミュニティ（業界・会社・部署・チームなど）によって相対的に変化するのです。

その相対的に変化する環境において、自分自身が「今、何者であるべきか？」を考え役割をスイッチしていくことができれば、「何者にもなれなかった私」でも、結果として「何者かになれている」状態を作り出せるのです。

「何者かになれている自分」を作り出せたら、炎の人のように「俺は俺の責務を全うする！」で一生懸命走れば良いのです。

# まとめ
* 「何者かでありたい」という幻想（過度なプレッシャー）は捨てよう
* 「何者でもない自分」「何者にもなれない自分」を受け止めよう
* 今、この状況、この環境で「何者であるべきか」を理解し、その役割（責務）を全うしよう
【MySQL】コンテナ名をホスト名として使用して『Unknown MySQL server host 'db' (8)』エラーが出た場合とは...

# 概要
- 以下のエラーが出ました（=MySQLサーバーへの接続に失敗）。
- 本記事ではこのエラーの解決方法を記します。

```
mysql.connector.errors.DatabaseError: 2005 (HY000): Unknown MySQL server host 'db' (8)
```

# エラー内容
- Dockerでは、デフォルトのネットワーク設定において、コンテナ名をホスト名として使用できる、とのことで、`'DB_HOST'`の環境変数にはDockerコンテナの名前`db`を設定しました。

```docker-compose.yaml
version: '3'
services:
  db:
    image: mysql
    environment:
      MYSQL_ROOT_PASSWORD: xxxx
      MYSQL_ROOT_HOST: '%'
    ports:
      - 3306:3306

  phpmyadmin:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: db
      PMA_USER: xxxx
      PMA_PASSWORD: xxxx
    ports:
      - 8080:80
    depends_on:
      - db
```

```py
import mysql.connector

# ローカルDBの接続情報
db_host = os.environ['DB_HOST']
db_port = os.environ['DB_PORT']
db_user = os.environ['DB_USER']
db_password = os.environ['MYSQL_ROOT_PASSWORD']
db_name = os.environ['DB_NAME']

db_connection = mysql.connector.connect(
    host=db_host,
    port=db_port,
    user=db_user,
    password=db_password,
    database=db_name
)

db_cursor = db_connection.cursor()
```

- ただし、これだと以下のエラー。

```
mysql.connector.errors.DatabaseError: 2005 (HY000): Unknown MySQL server host 'db' (8)
```

# 解決方法
- 環境変数`DB_HOST`を`db`から`localhost`にしたら解決しました。
- 今回、自分がローカル用に実行していたPythonのコードは、ホストマシン上のPython実行環境でした。一方、MySQLサーバーはDockerコンテナ内で実行されています。
    - `host='db'`と指定した場合：Pythonはホストマシン上の名前解決システムを使用して、`db`というホスト名を解決しようとする→しかし、ホストマシン上の名前解決システムはDockerコンテナ内のホスト名を知ることができない→エラー
    - `host='localhost'`と指定した場合：Pythonは自身が実行されているホストマシンを指すホスト名`localhost`を使用→ホストマシン上のMySQLサーバーに接続→`localhost`を正しく解決し、接続が成功
- つまり、Pythonのコードが実行されている環境（ホストマシン）からは、Dockerコンテナ内のホスト名を直接解決することはできないということ、でした。そのため、ホストマシン上のローカルホスト（`localhost`）を使って接続する必要があったのです。

## 備忘録
- 途中、以下のエラーも同じような経緯で発生しました。上記の対応をしたらなくなりました。

```
mysql.connector.errors.InterfaceError: 2003: Can't connect to MySQL server on 'db:3306' (8 nodename nor servname provided, or not known)
```
【Kubernetes】podのtimezoneを変更する

## タイムゾーンの設定・変更方法

yaml ファイルに以下を追記
```XXX.yaml
spec:
  env:
    - name: TZ
      value: Asia/Tokyo
```

Kubernetesでサポートしているタイムゾーンは下記。

https://www.alibabacloud.com/help/en/container-service-for-kubernetes/latest/time-zones

## 動作確認

```
kubectl exec {pod NAME} -n {名前空間} -it -c {deployment name} -- date
```

### 実行結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/261934/b1b02992-8974-ba75-f8a4-d95329fe2ab2.png)
OutSystemsで素数判定

# 概要
そのまんま、受け取った数値の素数判定を行うアクションです。
For Eachウィジェットを使わないループのサンプルとしても。

# プログラムの構成
## Client Action
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189679/ca65dac0-49ec-85f3-0698-d7f76e49d5e7.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/189679/dd5a310d-443f-f6b3-fff7-27a8a135435e.png)

### Input Parameter
* `InputNumber`
    * Integer
    * ユーザが入力する素数判定対象の整数値。

### Output Parameter
* `IsPrimeNumber`
    * Boolean
    * 素数判定結果。素数なら`True`、素数でないなら`False`。

### Local Variable
* `LoopCount`
    * Integer
    * Default Value: `2`
    * ループカウンタ。処理の最初で1までの数は弾いてしまうので開始は2になります。

# 解説
## InputNumber<=1?
素数の定義として「2以上の自然数である」があるので、問答無用で1以下の数値は`False`です。
このためループカウンタのDefault Valueは2になります。

## LoopCount<=Sqrt(InputNumber)?
素数の主要な定義は「正の約数が 1 と自分自身のみである」です。なので、1ずつ増やして判定対象を割っていき、判定対象に辿り着くまでに割り切れる数があったら`False`、というのが基本的な考え方です。
が、素数の性質として判定対象まで検査しなくても「判定対象の平方根」まで検査すれば判定可能というものがあります。これに従って判定条件を考えると上記になります。
`Sqrt(decimal)`はOutSystemsのBuilt-in Functionで引数の平方根を返す関数です。Mathの中にあります。

## Mod(InputNumber,LoopCount)=0?
実際の判定部分です。見ての通り、`InputNumber`を`LoopCount`で割った余りが0なら`False`、0以外なら`LoopCount`をインクリメントして処理を繰り返します。
`LoopCount`が`InputNumber`の平方根に届くまで繰り返して一度も割り切れなければ`True`、素数と判定します。
ここで、インクリメントした後にもう一度「`LoopCount<=Sqrt(InputNumber)?`」のIfウィジェットに戻っているところが肝で、これでFor Eachウィジェットを使わないループが実現できます。
【ServiceNow】Utahリリース「フローダイアグラムでのステージのサポート」

# はじめに

みなさんこんにちは、三井情報株式会社です。
今回はUtahへのバージョンアップで新規追加された「フローダイアグラムでのステージのサポート」についてご紹介致します。

# フローダイアグラムビューとは

フローダイアグラムビューとは作成したフローを図に変換してくれる機能です。
見た目が大きく変わり、通常ビューよりわかりやすくなっています。

# フローダイアグラムビューでのステージ表示

通常ビューにてアクションを追加した後、フローダイアグラムビューに切り替えるとステージが表示されています。

![FlowDesigner.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/f120d541-8569-a635-ac89-746c1777c32a.png)
![FlowDiagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/27d7ad2d-d830-3ef0-0c31-644eb903c89f.png)

# フローダイアグラムビューでのステージ追加

フローダイアグラムビューにおいてもステージの追加が可能です。
通常ビューと同じくアクション間の矢印にカーソルをあてて+ボタンを押下しステージを選択します。

![FlowDiagramStage.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/ef9b2253-72bb-e3a3-d4a5-69bc7e9aec9c.png)
![FlowDiagramStageSelect.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/d4ebcc25-7509-ea41-150b-5366b2dfde30.png)
![FlowDiagramStageAdded.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2599899/78a46449-2653-a866-b576-891612f9d2c9.png)

# 参考

フローダイアグラムビューについては下記記事もご参照ください。
https://qiita.com/sakuma-iho/items/8331d8a6925becfd3829

# おわりに

今回はUtahへのバージョンアップで新規追加された「フローダイアグラムでのステージのサポート」についてご紹介させていただきました。
最後まで読んでいただき、ありがとうございました。
OpenCV 画像の一部を切り出す:座標指定・スライシング

# 概要
OpenCVの基礎を固めます．第2回目は画像のトリミングに取り組みました．

# OpenCVとは
・Pythonライブラリの1種
・Intel提供のOSS
・画像・動画処理専門ライブラリ
・Pythonの一般的な前処理ライブラリとして挙げられる

メリット
・DPL用の前処理が簡略化でき容易
・ 多様なライブラリと相互性がある

# 環境
Windows11,VSCode,python(3.10)

# 画像の一部を切り出す:座標指定・スライシング

画像は自分で撮影したケーキの画像cake.jpgを使います．
コードの先頭にimport cv2でライブラリをインポートし，OpenCVを使えるよう準備します．

```PHP:Trimming.py
#OpenCVのインポート
import cv2
```

画像のwidth×heightを調べます．print関数にimg.shapeと記載し，画像サイズは360×478と分かりました．スライシングはimg[top:bottom,left:right]に取り出したい座標を指定します．

```PHP:Trimming.py
import cv2

img=cv2.imread("cake.jpg")
print(img.shape)
#(360, 478, 3)  (縦幅,横幅,色相数)を表しています．

timg=img[100:250,200:340]
#切り抜きたい部分の座標を入力

cv2.imwrite("timg.jpg",timg)
cv2.waitKey(0)
```
色相数についてコメントアウトで触れていますが，3はカラー画像(RGB),2は二値画像(白黒)を表現しています．

# 結果

出力画像は以下のtimg.jpgの結果になりました．元画像のケーキの飾り部分が抜き出せていますね．

![scakeR.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330338/1826fb83-3c0c-4d75-041d-34dbf9ce758c.jpeg)


# スライシングについて

今回のスライシングはトリミング方法の1つを紹介したものです．
この方法は任意の座標で，好きなサイズに画像を抜き出すことができます．(もちろん画像の縦横幅以内の範囲でですが)

スライシングについての図解をしていたサイトがあったので，自分でも理解の為に図解を作ってみました．

![srice.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3330338/643b1efb-b756-ca9a-d717-60bb8ecacb76.jpeg)

スライシングは分割の意味があり，これをトリミングに用いている方法です．
上の図は処理のイメージです．座標を用いて四角形に切り出して抽出します．
privateGPTでargostranslateを使って自動翻訳チャット

完全プライベートなprivateGPTにオフラインで使えるargostranslateを組み込んで、入力ファイルとチャットのやりとりを翻訳するようにしてみました。

https://github.com/etsuhisa/privateGPT

readmeの最後に出力例を載せましたが翻訳の精度が少々悪いです。
privateGPTもそれなりに時間がかかるのに加えて翻訳にも時間を要します。
念のためargostranslateが翻訳中に通信していないことをキャプチャを取って確認しました。

仕組みは単純です。

- ingest.py
ファイルを読むときにdoc.page_contentをargostranslateで英語に翻訳して登録します。

- privateGPT.py
日本語で入力した質問を英語に翻訳して、英語で返ってきた応答を日本語に翻訳して表示します。
アイドリングタイム：世界に一つだけの花を作る

たからもののプログラムを他人になかなか紹介できない経験がありますか。それならばCodeFlowerでやってみましょう。以下はCodeFlowerの元家です。JSONデータを読み込んでd3ツールで可視化するやりかたです。

http://www.redotheweb.com/CodeFlower/

自分のほうは、それをベースにしてもうちょっと使いやすいものを改善してみました。
# 環境構築
tomcat789のいずれ＋jdk8以上にします。アプリは、以下のURLからダウンロードしてください。
https://github.com/efwGrp/qittaSamples
jdk15以上は追加jarが必要です。上記サイトから入手してWEB-INF/libに入れてください。

# jsp説明
codeflower.jspには、elfinderのファイル管理を置いています。作成ボタンはjsイベントを実行します。※これだけです。
```jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ taglib prefix="efw" uri="efw" %> 
<!DOCTYPE HTML>
<HTML>
<HEAD>
	<META HTTP-EQUIV="CONTENT-TYPE"CONTENT="TEXT/HTML;CHARSET=UTF-8">       
	<TITLE>efw Input Test</TITLE>
	<!-- Efwクライアントの取り込み-->
	<efw:Client lang="jp"/>
</HEAD>
<BODY>
	<h1>世界に一つだけの花を作りましょう</h1>
	<efw:elFinder home="upload" />
	<br>
	<button onclick="Efw('codeflower_create')">作成 & ダウンロード</button><br>
</BODY>
</HTML>
```
# jsイベント説明
コメントで説明しますね。
```javascript
var codeflower_create={};
codeflower_create.paramsFormat={};
codeflower_create.fire=function(params){
	//再帰的にuploadファイルの中身を分析してJSONを作成する。
	function getChildrenFromFolder(folder){
		var lst=absfile.list(folder,true);
		var ret=[];
		for(var i=0;i<lst.length;i++){
			var item=lst[i];
			if(item.mineType=="directory"){
				if (!item.isHidden)//非表示フォルダを対象しない
				ret.push({"name":item.name,"children":getChildrenFromFolder(item.absolutePath)});
			}else{
				var size=Math.sqrt(item.length);//ファイルサイズの平方根の数字で画面の円の大きさを決める
				var showSize=(item.length/1000).format("#,##0.0")+" kb";
				ret.push({"name":item.name,"size":size,"showSize":showSize});
			}
		}
		return ret;
	}
	//テンプレートを読む
	var html=file.readAllLines("template/template.html","UTF-8");
	//uploadフォルダの内容でJSONを作成
	var json={"name":"root","children":getChildrenFromFolder(file.getStorageFolder()+"/upload")};
	//テンプレート内容にJSONを代入する。
	html=html.replace("{@@@@}",JSON.stringify(json));
	//htmlファイルを作成する
	file.writeAllLines("myflower.html",html,"UTF-8");
	return (new Result())
	.runat("body")
	.attach("myflower.html")//ダウンロード
	.deleteAfterDownload();//サーバファイルを削除
}
```
# 花を作る
プロジェクトフォルダをelFinderにドラッグ＆ドロップします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/a2b68e79-1082-e3af-201a-42227dfdd0cd.png)
作成ボタンを押して、ファイルが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/dd6ef4e7-40cd-f4a0-4297-1362e3ed7fd7.png)
ファイルを開くと綺麗な花（アジサイか）が咲きますね！それぞれのプロジェクトはそれぞれのソースコード特徴で、「世界に一つだけの花」になりますよね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476221/cb139734-50ba-b744-f05b-ec26127fbc32.png)

一つずつの円をマウスで当たると名称とサイズを表示されます。URLはこちらです。
https://efwgrp.github.io/efw4_codeflower/efw4.X.html

利用するjsファイルは、WEB-INF/storage/template/template.htmlのテンプレートファイルに記載しています。それらのファイルは、サンプルフォルダから入手できます。

今回のサンプルは以下のリンクからダウンロードできます。

https://github.com/efwGrp/qittaSamples
React18でReactDOM.renderを使ったらイベントが発火しない！？

# 概要
先日、とあるハッカソンに参加し、chrome拡張を作ることになり、Reactを使いました。せっかくなのでReact18を使って作っていたのですが、popupとoptionページでなぜか`onClick`などのイベントが発火しなかった。ビルド時にエラーや警告もなく、React18を使うことやChrome拡張を作るのは初めてだったので、Chrome拡張の仕様？（そんな訳ない！！）と思ってしまいました。ところがどっこい`pnpm run watch`をしたらこんな警告が出るではないか...

```sh
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
```

# 前提
- Reactでchrome拡張を開発している
- Webpackの設定を書いてpopupやoptionsのファイルをビルドするようにしている

## バージョン
- "react": "^18.2.0"
- "react-dom": "^18.2.0"
- "webpack": "^5.86.0"
- "webpack-cli": "^5.1.4"
- "webpack-merge": "^5.9.0"

# 症状
警告

```sh
Warning: ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
```
日本語訳
```sh
警告：ReactDOM.render は React 18 ではサポートされなくなりました。createRoot を使用してください。新しい API に切り替えるまで、アプリは React 17 で実行されているかのように動作します。詳細については、こちらをご覧ください：https://reactjs.org/link/switch-to-createroot
```

# 解決策
解決策は非常に簡単！

```react
ReactDOM.render(<Options />, document.getElementById('root'));
```
↑を↓に書き換えるだけ

```react
const container = document.getElementById('root');
const root = createRoot(container!);
root.render(<Options />);
```

# まとめ
`create-react-app`などでプロジェクトを立てていればこんなことにはならなかったと思う。同じ過ちを犯さないように気をつけたい。
Reactでevent.target.valueして知ったこと

ReactでAPIを使用した簡単なアプリを作成しています。
その中で学んだことを自分が後で見返せるように書き残します。

## onChange
onChangeイベントには最初からeventが付いてる。
非推奨の方を書いても動いたがvscode上でeventに取り消し線が引かれて非推奨表示が出た。

推奨
```React
function handleChange(event) {
  console.log(event.target.value);
}

<input type="text" onChange={handleChange} />
```

非推奨
```React
function handleChange(event) {
  console.log(event.target.value);
}

<input type="text" onChange={(event) => handleChange(event)} />
```
std::cin「空白文字？　いえ、知らない子ですね」

# プロローグ

ある日、う　し　た　ぷ　に　き　あ　く　ん　笑はう　し　た　ぷ　に　き　あ　王　国　笑の王様の命令でテキストファイルの内容をすべて読み込んて出力するコードを書きました。

```text:u_shi_ta_pu_ni_ki_a_ku_n_lmao.txt
う  し  た  ぷ  に  き  あ  く  ん  笑
```

```c++:read_all.cpp
#include <iostream>
#include <fstream>
#include <string>
#include <iterator>

int main() {
    std::ifstream ifs{ "u_shi_ta_pu_ni_ki_a_ku_n_lmao.txt" };
    std::string s(std::istream_iterator<char>{ ifs }, {});  // ファイルの内容を全部コピーしたつもり

    std::cout << s;
}
```

しかし、実行結果は次のようなものでした。

```text:出力
うしたぷにきあくん笑
```

空白文字がなくなってしまっています。
このままでは王様が怒ってう　し　た　ぷ　に　き　あ　く　ん　笑はう　し　た　ぷ　に　き　あ　王　国　笑から追放されてしまうかもしれません。



# `std::cin >> c` は空白を読み飛ばす

C++の書式化入力（ `>>` を使った入力）では空白文字が読み飛ばされます。
`std::istream_iterator` では `>>` が使われるので、空白文字が読み込まれなかったというわけです。

`scanf("%c", &c)` では空白文字も読まれるので、う　し　た　ぷ　に　き　あ　く　ん　笑は勘違いしていたようです。

しかし、非書式化入力関数を使ったコードに書き換えるのは面倒です。
何か楽な方法はないでしょうか？



# `std::noskipws` マニピュレータ

`std::noskipws` は書式化入力で空白文字を読み飛ばさないことを指示するマニピュレータです。

https://cpprefjp.github.io/reference/ios/noskipws.html

これを使えば、修正は最小限で済みます。
早速さっきのコードを書き換えます。

```diff_cpp:read_all.cpp
  #include <iostream>
  #include <fstream>
  #include <string>
  #include <iterator>
  
  int main() {
      std::ifstream ifs{ "u_shi_ta_pu_ni_ki_a_ku_n_lmao.txt" };
+     ifs >> std::noskipws;
      std::string s(std::istream_iterator<char>{ ifs }, {});
  
      std::cout << s;
  }
```

実行してみると次のようになりました。

```text:出力
う  し  た  ぷ  に  き  あ  く  ん  笑
```

しっかり空白も含めて出力されています。
これなら、う　し　た　ぷ　に　き　あ　く　ん　笑は王様に怒られずに済むでしょう。



# エピローグ

全角スペースの代わりに半角スペース2個を使っていたので、う　し　た　ぷ　に　き　あ　く　ん　笑は追放されました。
Python 改行コード変換(Windows環境)

コメントいただきましたので、修正してみました

Windows 環境の Python で、クリップボード上のテキストの混在する改行コード(\r\nと\n)を統一する

```python
import os
import pyperclip
line =pyperclip.paste()
line =line.replace(os.linesep, "\n")
line =line.replace("\n", os.linesep)
pyperclip.copy(line)
```

コメントありがとうございます。
os.linesepを使うのが正解のようですね。
最初のreplaceで\r\nを\nに変換することで、改行コードを\nに統一し、
次のreplaceで\r\nにしてクリップボードに戻しています。

ただし、入出力がファイルの場合は、テキストモードのopenでうまくやってくれるんですね...

また、\rも変換してましたが、古い人間なもので、古いMacの改行コードも想定してました...