OmniAICreator/Qiita-1.07M huggingface dataset:
LinuxにおけるGitHubのお手軽な使い方

# キー
まず、GitHub用のSSHキーとGPGキーを作成して登録する。両者ともに専用のキーを使い、会社用と個人用などで使い分けられるようにする。

## SSHキーを作成
```
ssh-keygen -t ed25519 -N '' -C '' -f ~/.ssh/id_ed25519_hydratlas
```

## 代替ホスト名とSSHキーの組み合わせを~/.ssh/configに追記
```
nano ~/.ssh/config
```

```
Host github-hyd
    HostName github.com
    IdentityFile ~/.ssh/id_ed25519_hydratlas
    User git
```

## GPGキーを作成
GitHubが、GitHubに登録したメールアドレスを隠すためのメールアドレスを用意してくれているため、それを https://github.com/settings/emails で確認して使用する。
```
gpg --pinentry-mode loopback --passphrase '' --quick-gen-key \
  'hydratlas <160527126+hydratlas@users.noreply.github.com>' \
  future-default - 0
```

## GPGキーを確認
```
gpg --list-secret-keys --keyid-format LONG
```

```
/home/hydratlas/.gnupg/pubring.kbx
-----------------------------
sec   ed25519/F42BDA4E5020D58E 2024-03-05 [SC]
      302B4894754005BAD5FC21C5F42BDA4E5020D58E
uid                 [  究極  ] hydratlas <160527126+hydratlas@users.noreply.github.com>
ssb   cv25519/25AD91FADDEF6786 2024-03-05 [E]
```

## GitHubにSSHキー・GPGキーを登録
```
cat ~/.ssh/id_ed25519_hydratlas.pub

gpg --armor --export 302B4894754005BAD5FC21C5F42BDA4E5020D58E
```
表示した内容を https://github.com/settings/keys に登録する。

# リポジトリの作成またはクローン
## 作成
まずGithub側でリポジトリを作ってから以下のコマンドを実行する。
```
git init --initial-branch=main &&
git remote add origin git@github-hyd:hydratlas/<name>.git
```
必要に応じて.gitignoreファイルを作り、除外ファイルを指定する。

## クローン
```
git clone git@github-hyd:hydratlas/<name>.git
```

# git config
```
cd tips &&
git config user.name 'hydratlas' &&
git config user.email '160527126+hydratlas@users.noreply.github.com' &&
git config commit.gpgsign true &&
git config user.signingkey 25AD91FADDEF6786
```
`gpg --list-secret-keys --keyid-format LONG`のssb欄（cv25519/25AD91FADDEF6786）を参照する

# リモート(Github)での変更をローカルに反映させる
```
git pull origin main
```

# ローカルでの変更をリモート(Github)に反映させる
```
git add --all &&
git commit -m "" --allow-empty-message &&
git branch -M main &&
git push -u origin main
```
コミットメッセージはできれば書いたほうがよい。
Spring Cloud Gatewayを使用してAPIゲートウェイを構築してみた

## Spring Cloud Gatewayとは？

Spring Cloud Gatewayは、Spring BootフレームワークとSpring Cloudプロジェクトの一部であるAPIゲートウェイで、シンプルかつ効果的な方法でAPIへのルーティングを提供し、セキュリティ、監視/メトリクス、回復力などの横断的な関心事をAPIに提供することを目的としている。

#### 主な機能

- ルーティング: さまざまな条件に基づいてリクエストを適切なサービスにルーティングする
- フィルター: リクエストとレスポンスを処理するフィルターを適用できる
- 認証と認可: OAuth2、JWTなどの認証と認可メカニズムをサポートする
- 監視: Prometheus、Micrometerなどのツールを使用してAPIの使用状況を監視できる
- サーキットブレーカー: 障害が発生したサービスへのリクエストを自動的に遮断し、システム全体の安定性を保つ

## APIゲートウェイとは？

APIゲートウェイは、複数のAPIをまとめて管理するためのプラットフォームで、APIの開発、公開、保護、監視を容易にし、開発者とバックエンドサービス間の仲介役として機能する。

#### 主な機能

- APIの公開と管理: APIを安全かつ効率的に公開し、バージョン管理や認証、アクセス制御などの機能を提供する
- セキュリティ: APIへのアクセスを制御し、悪意のある攻撃から保護する
- 監視と分析: APIの使用状況を監視し、パフォーマンスやエラーを分析する
- 開発者向けツール: APIの開発とテストを容易にするツールを提供する

## プロジェクトを作成する

Project: Maven
Language: Java
SpringBoot: 3.2.4
Group: dev danvega
Artifact: gateway-demo
Name : gateway-demo
Description: SCG Demo
Package name: dev danvega gateway-demo
jar 21

Dependencies
Gateway

## コードを編集する

①resources/application.properties　⇨ application.yamlに名前を変更し、編集する

```resources/application.yaml
spring:
  cloud:
    gateway:
      routes:
        - id: posts-route
          uri: http://localhost:8081
```
②下記のコードを追記する
```pom.xml

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
    <version>3.1.2</version>
</dependency>

```




## 参考サイト
[Building an API Gateway in Java with Spring Cloud Gateway](https://www.youtube.com/watch?v=EKoq98KqvrI)
[Spring Cloud Gatewayで流量制限をかける](https://qiita.com/3087KT/items/658afe3dacdce50c490e#:~:text=2023%2D07%2D02-,Spring%20Cloud%20Gateway%E3%81%AE%E6%A6%82%E8%A6%81,%E3%81%99%E3%82%8B%E5%BD%B9%E5%89%B2%E3%82%92%E6%9E%9C%E3%81%9F%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
Unityエラー対応　Resolving Android Dependencies Stuck at 0%

解決の仕組みがよくわかっていないので行うのは自己責任で
## 問題
gradlew.batがない、パスが違うことによるエラー
この画面で止まる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/079f2d9f-641c-40e1-7757-a8afec4112da.png)


## 対処方法
アセット>モバイル依存関係リゾルバー>Androidリゾルバー>解決されたライブラリを削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/60a8b6ef-21b3-4602-3649-dbfb51c39366.png)
Echoで固有リクエストヘッダ検証によるCSRF対策

## CSRF対策
CSRF対策で重要なのはユーザーが意図しない動作をブロックすることだと考えました。一般的なCSRF対策としてはCSRFトークンを利用したものがありますが、実装がうまくいきませんでした。色々試行錯誤してる中で、そもそもバックエンドとフロントエンドが独立したSPAでこれが適しているのかどうかという疑問も同時に持ちました。同じような問題の解決方法がMPAに限定されたものばかりだったためです。
https://echo.labstack.com/docs/middleware/csrf

そこで調べているとバックエンドとフロントエンドが独立したSPAでは上の実装が困難であることを見つけ、下記ページで紹介されていた「固有のヘッダの有無を検証する」を試しました。
https://kimuson.dev/blog/フロントエンド/csrf_spa/

## 実装
「固有のヘッダの有無を検証する」middlewareの実装。
middlewareの実装は試行錯誤していた時に見ていたechoの`csrf.go`を参考にしました。
https://github.com/labstack/echo/blob/master/middleware/csrf.go

```go
func tokenCheck(next echo.HandlerFunc) echo.HandlerFunc {
	return func(c echo.Context) error {
		var tokenErr error

		if slices.Contains(
					[]string{http.MethodGet, http.MethodHead, http.MethodOptions, http.MethodTrace}, 
					c.Request().Method) {
			return next(c)
		}

		csrf_token := getCSRFTokenFromHeader(c)
		if reflect.ValueOf(csrf_token).IsValid() != true {
			return tokenErr
		}

		return next(c)
	}
}

func getCSRFTokenFromHeader(c echo.Context) string {
	token := c.Request().Header.Get(<TOKEN>)
	return token
}

func main() {
    e.Use(tokenCheck)
}
```
これで固有ヘッダ「TOKEN」が含まれているリクエストは通し、それ以外のものはエラーを出すようなミドルウェアの実装ができました。

## 有効性
今回初めてCSRF攻撃についてちゃんと調べたので、正直正しい理解かは分かりませんが、自分なりに今回の対策の有効性を考えました。

「CSRF対策で重要なのはユーザーが意図しない動作をブロックすること」は今回の対策で出来ていると思います。固有ヘッダを付随しなければ、リクエストを弾けるからです。
そしてリンク先を読む感じでは、ヘッダが設定された攻撃の場合には、攻撃を「CORS設定」によって防げると考えています。
VScode・GitHubの連携 | 新しいプロジェクトの作成

# 新しいプロジェクトを立ち上げる
　GitHubとVSCodeを用いて新しくプロフェクトを立ち上げる際にやるべきことをまとめた。
## 下準備

### 1. フォルダの作成
　プロジェクトに必要なファイルを入れるためのフォルダを自分のPC上のどこかに作成する。
### 2. リポジトリの初期化
　Gitを利用するためにローカル上でリポジトリを作成する。VSCodeにて1で作ったフォルダを開き、`リポジトリの初期化`というボタンを押す。
 ![リポジトリの作成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/0941c709-1511-f2c6-f40a-b28438c2ffd6.png)

## ローカル上でのアップロード
　新しくファイルを追加したり、内容を追加・書き換えしたりすると、ローカルリポジトリに保存する必要がある。これを`コミット(commit)`という。
### 1. ステージングエリアへの保存
　ローカルリポジトリにコミットするには、その前にまずステージングエリアという場所に変更内容を保存しなければならない。このことを`add`という。
　（ローカルリポジトリやステージングエリア、リモートリポジトリの関係性が分かりづらければ、これらのワードで検索して画像を調べると分かりやすい図がたくさん出てくる。)
 
 　ソース管理のウィンドウを開き、変更という欄のファイルにカーソルを合わせて＋ボタンを押す。これでステージングエリアへのaddが完了。
 ![ステージングエリアへのadd.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/35c3662d-5643-9535-00ee-0224b021aef1.png)

### 2. ローカルリポジトリへのコミット
　1でステージングエリアに保存したことによってローカルリポジトリへコミットすることが可能になった。
 メッセージを入力して`コミット`を押せばローカルリポジトリへの保存が完了する。
![ローカルリポジトリへのコミット.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/8c0e08ce-bf2a-5349-f06b-18f1657a6d70.png)


## GitHubとの連携
　GitHubと連携することによって、チーム開発や複数のデバイスを使った製作がとても便利になる。
 ### 1. GitHub側でリポジトリを作成
 　連携をするには、まずGitHub側にプロジェクトを保存するための受け皿となるリポジトリを作成しておかなければならない。
  GitHubアカウントから新しいリポジトリを作成する。名前は自由、Descriptionにはそのプロジェクトの説明文を書きたければ書き、コードを公開したくない場合はprivateを選択して新規作成。
![リポジトリ作成(GitHub).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/4e462684-3af4-1b27-0277-d9fe62c1b78d.png)

### 2. GitHubとVSCodeの連携
　現段階ではGitHubとVSCodeの連携が取れていないため、リモートの設定をする。
 　先ほどと同じくソース管理のウィンドウを開き、右上の`・・・`から`リモート`＞`リモートの追加…`を選択。GitHubからコピーしてURLを直接入れるか、VSCode上で選ぶかして連携させる。
![github urlコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/a1d9814d-07b9-aeb3-2a54-876c7699c678.png)
![GitHub連携　選択.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/b96c801a-f1e6-43a3-21b0-8c6830176751.png)
　その後のリモート名は特に理由がなければ最初は「origin」とする。
![github リモート名.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/e8396a69-dfc5-16a6-08e4-a4c8d107463a.png)

### 3. リモート上へのアップロード
　ローカルリポジトリの変更内容をリモートリポジトリへ保存することを`プッシュ(push)`という。
　ソース管理のウィンドウの`Branchを発行`かウィンドウの下のクラウドマークを押すとプッシュが完了する。
![GitHub　プッシュ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/21c5f797-fd39-934d-f5ff-7990d5ff3d20.png)

## 連携完了
　これらの操作を行った後GitHubをもう一度開きなおすと、ちゃんとファイルが保存・更新されているはず。
 ![GitHub連携完了.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3585986/d40b8c7f-e927-5168-ee0e-69c0bbebc1e9.png)
　VSCodeを使うととても簡単にGitを扱うことができるので、ぜひ活用してほしい。

## 参考文献
- Visual Studio Codeで学ぶ Git + GitHub
　https://www.youtube.com/watch?v=O8FWIWTXYQw
- VSCodeでのGitの基本操作まとめ
　https://qiita.com/y-tsutsu/items/2ba96b16b220fb5913be#%E3%83%97%E3%83%83%E3%82%B7%E3%83%A5%E3%81%99%E3%82%8B
- 【GitHubの使い方入門】GitHub Pagesを使って世界中にサイトを公開しよう！アウトプットこそ学びだ！
　https://www.youtube.com/watch?v=kftqAritHyc
Unity　バナー広告を付ける

## 手順
GameIDの発行
Unity　Cloudへログインし

https://cloud.unity.com/
ダッシュボード
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/cf5ba354-0fd8-0ce8-6910-79c553a96ed5.png)

広告を使いたいプロジェクトを選ぶ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/88682c1d-801b-378d-13f2-e4cdbe89725a.png)
シュートカットからUnityAdsを選んで
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/85a3ebed-fd6a-e19c-3fad-2b1547644164.png)
GetStarted
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/03b21856-92bb-3cf7-78ee-541720cb4420.png)
UniytでAndroidなら以下の選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/847ef274-e565-50fc-b30e-10a6e600bcbc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/cd71ace3-965a-8ccb-cb52-df8ed81618af.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/8221ab16-316d-c5c0-5b1e-780e42080d5c.png)
すでにリリースしているならそのURLを張る
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/4f2d7604-b2b4-4f9d-4de1-fcf0a961b476.png)

これでGameIDが発行される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/6504f823-484c-6a81-f8f1-f89e6e44ce6c.png)

実行するにはテストモードにリリースするときに解除すること
Unity Ads Monetization の設定から
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/f4eab249-37d3-90a7-f00a-8913d79981b0.png)
一番下のテストモードを変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/796aaa51-8fce-022b-56f7-c30803309af3.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/3b6071af-ac05-d546-1222-e241ad44b762.png)



## ADS Packagesのインストール
Pacage Managerから
Ads mediation
Advertisement Legacyをインストール
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/9fb83fc7-0fd0-85f6-4d6c-b0a84e53f6ae.png)


## スクリプトで実装

```
using UnityEngine.Advertisements;
```
```
[SerializeField] string _androidAdUnitId = "生成したID";
void Start()
{
    //バナーの位置
    Advertisement.Banner.SetPosition(BannerPosition.TOP_CENTER);
    Advertisement.Banner.Load(_androidAdUnitId);
}
//適当なボタンで実行させる
public void ShowBannerAd()
{

    Advertisement.Banner.Show(_androidAdUnitId);
}
```
これを適当なボタンで実行させるとバナーが表示される
![Animation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2294598/c5311c5d-9e49-c9e9-aba2-ab5166e34e39.gif)
## もう少し詳しく
https://docs.unity.com/ads/ja-jp/manual/ImplementingBannerAdsUnity

公式のドキュメントにAndroid、IOSのID切り替えと広告が読み込まれなかった時に呼ばれるコールバックの設定があるので基本的にはこれを参考にすること

ここまでくればもうできるはず。やったね。
## 参考サイト

https://note.com/yasuyuki_kamata/n/n5bfc51e99684

https://docs.unity3d.com/ja/560/Manual/UnityAdsHowTo.html

https://docs.unity.com/ads/ja-jp/manual/ImplementingBannerAdsUnity
[競プロ] bits/stdc++.hがインクルードできないときの対処

## 環境
Windows 10、vscode 1.87.0、mingw32 9.2.0、
## 症状と状況
#include\<bits/stdc++.h\>を書いたときに、"#include エラーが検出されました。includePath を更新してください。"というエラーが出てしまう。また、**C/C++というMicrosoftが作っている拡張機能**をインストールした後にエラーが出るようになった。
## 原因
**c_cpp_properties.json**のインクルードパスにbits/stdc++.hが含まれていなかった。また、コンパイラーなども予想していたものと異なるものが設定されていた。このファイルは、**C/C++**の設定ファイルであり、プロジェクトと同じ階層の.vscodeというフォルダの中に含まれている。
## 対処
自分は、mingw32をインストールしていて、g++でコンパイルしたかったため以下のようにインクルードパスを書き直した。結果、エラーが出なくなった。
```json:c_cpp_properties.json
{
    "configurations": [
        {
            "name": "Win32",
            "includePath": [
                "${workspaceFolder}/**",
                "C:\\MinGW\\include",
                "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++",
                "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++\\mingw32",
                "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++\\mingw32\\bits",

            ],
            "defines": [
                "_DEBUG",
                "UNICODE",
                "_UNICODE"
            ],
            "windowsSdkVersion": "10.0.22000.0",
            "compilerPath": "cl.exe",
            "compilerPath":"C:\\MinGW\\bin\\g++.exe",
            "cStandard": "c17",
            "cppStandard": "c++17",
            "intelliSenseMode": "gcc-x64"
        }
    ],
    "version": 4,
    
}
```

なお、vscode標準のsetting.jsonというファイルにて、以下のように記述するとこの設定をしなくてもよくなる。ただし、c_cpp_properties.jsonのファイルに競合する内容が記述されていた場合、後者が優先されてしまうため、注意が必要。(後者の競合する部分はコメントアウトするなどして対処する必要がある。)

```json:setting.json
{
 //省略
"C_Cpp.default.includePath": [
        "${workspaceFolder}",
       "C:\\MinGW\\include",
       "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++",
       "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++\\mingw32",
       "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++\\mingw32\\bits",
       "C:\\MinGW\\lib\\gcc\\mingw32\\9.2.0\\include\\c++\\mingw32\\bits\\stdc++.h",

    ],
    "C_Cpp.default.compilerPath": "C:\\MinGW\\bin\\g++.exe",
    "C_Cpp.default.cppStandard": "c++14",
    "C_Cpp.default.intelliSenseMode": "gcc-x64",
}
```
GitHubのAutoLinkでBacklogの課題を参照しやすくした

# はじめに
　所属している開発チームでは、タスク管理にBacklogを、ソースコードの管理にGitHubを使っています。コミットメッセージ・ブランチ名・プルリクにBacklogの課題キーを入れて、コード変更とタスクとを関連付けています。
 　しかしタスク内容を確認するためには、毎回Backlogを開いてGitHubに書かれた課題キーで検索する必要があり、手間でした。
  　タスク確認を楽にするため、**AutoLink機能**を導入し、GitHubからBacklogの課題を参照できるようにしました。
   
# AutoLinkとは
　GitHubのAutoLink機能は、コミットメッセージ・ブランチ名・プルリクに特定の文字列が含まれている場合に、その文字列に対して自動的にリンクを生成する機能です。この機能を使って、Backlogの課題キー (PROJECT-000) に自動的にリンクを付け、GitHub上から直接Backlogの課題ページへアクセスできるようにしました。

:::note warn
GitHubのプランによっては使用することができません。
詳細は[参考](#参考)に記載したGitHub公式ページをご確認ください。
:::

# 設定方法
### 1. GitHubリポジトリの設定にアクセス
設定を行いたいリポジトリにアクセスし、上部メニューの「Settings」をクリック
### 2. AutoLinkの設定へ移動
左のメニュー最下部にある「Autolink references」をクリック

![qiita.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712137/e88e561d-c128-6b1e-42c7-5f917214c8e5.png)

### 3. 「Add autolink reference」をクリック
![qiita2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712137/8f0aaa3a-8a89-5f26-6e1e-b007e266a52b.png)


### 4. Autolinkのパラメータ入力
Autolinkの設定画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712137/958312ed-5159-94e7-31a0-388cecd30b66.png)
- Refrenceprefix
リンクとして設定したい文字列(Backlogの場合は課題キー)
**e.g.)** PROJECT-
- Target URL
GitHubから飛びたいリンク先のURL
**e.g.)** Backlogの場合：
```
https://hoge.backlog.com/view/PROJECT-<num>
```
\<num\>にはPrefixで設定した文字列より後ろの値が自動的に代入され、URLが作成される仕組みです。
代入される値は、「Alphanumeric」なら英数字すべて、「Numeric」なら数字だけになります。
**e.g.)** ブランチ名：PROJECT-777-developの時作成されるリンク
```
Alphanumeric:
https://hoge.backlog.com/view/PROJECT-777-deveplop
Numeric:
https://hoge.backlog.com/view/PROJECT-777
```

最後に「Add autolink reference」をクリックして設定を反映させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712137/a248668f-aed1-8820-68e5-a1deb67b4f3d.png)
### 反映後
一度設定すると、削除以外に設定変更する方法がないため注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712137/28d3474c-ea70-46cf-cc62-a56bc759140d.png)


# 参考
[外部リソースを参照する自動リンクの構成 / GitHub](https://docs.github.com/ja/repositories/managing-your-repositorys-settings-and-features/managing-repository-settings/configuring-autolinks-to-reference-external-resources)
[Pandas]全て0の行・列を削除する

Pandasで値が全て`0`の行・列を削除する方法です。

## 推奨
```python
# 全て0の行を削除する
df = df.loc[(df != 0).any(axis=1)]

# 全て0の列を削除する
df = df.loc[:, (df != 0).any(axis=0)]
```


## （別方法）

```python 
# 全て0の行を削除する
df = df.mask(df==0).dropna(how='all', axis=0).fillna(0)

# 全て0の列を削除する
df = df.mask(df==0).dropna(how='all', axis=1).fillna(0)
```

**補足**
* 欠損値を含まない`pandas.DataFrame`であること。
* 上記コードの`0`を任意の値に置き換えてもOK。
* `.mask()`は、条件に一致する値に対して`True`を返し、これに対して置換したい値を第2引数に指定する。指定しない場合、`NaN`が置換されるので、上記ではこれを利用している。

</br>

* 欠損値を含む場合は、一度別の値に置換してから、処理後に戻せばよい。ただし、DataFrameの中に存在しない値を用いること。
```python
df = df.fillna(99999)
df = df.mask(df==0).dropna(how='all', axis=1).fillna(0)
df = replace(99999, np.NaN)
```
【Thymeleaf 】論理演算子を使用する際の注意点

## 背景
JUNITでControlelerのテストをしている際、以下の事象に遭遇した。

## エラーログ
```
Request processing failed: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "${isWorking} != null && ${jobChangeCount} != null" (template: "entryHistory/entry_history_apply_detail_pc" - line 265, col 37)
jakarta.servlet.ServletException: Request processing failed: org.thymeleaf.exceptions.TemplateProcessingException: Could not parse as expression: "${isWorking} != null && ${jobChangeCount} != null" (template: "entryHistory/entry_history_apply_detail_pc" - line 265, col 37)
	at app//org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011)
 ```

 要は、Thymeleafの書き方がいけなかったっぽい。。

 ## エラーが発生した箇所
 ```html
 <th:block th:if="${isWorking} != null && ${jobChangeCount} != null">
 ```

 ## 調査
論理演算子（and, or, not）を使うときに、&&とか||とか!を使ったらエラーになる。
使うなら、そのまま、and, or, notと記載する。


## 参考資料
https://zenn.dev/fujishiro/scraps/93b0a6d5e688a6

## 修正後
 ```html
 <th:block th:if="${isWorking} != null and ${jobChangeCount} != null">
 ```





これでOK！
クラスの継承

https://paiza.jp/works/mondai/class_primer/class_primer__inheritance

さて、これもなかなかあまりないので
手探りでやってみましたがだめでした。

```py
class Ghest():
    def __init__(self,number,food_name,age,order):
        self.number = int(number)
        self.food_name = food_name
        self.age = int(age)
        self.order = int(order)
        
    def __str__(self):
        """表示文字列に変換する"""
        return f"{self.number} {self.food_name} {self.age} {self.order}"
        
    
    def getnum(self):
        return self.number
    
    def getname(self):
        return self.food_name
        
    def getage(self):
        return self.age
        
    def getorder(self):
        return self.order
        
    def sumup_order(self,food_name,new_order):
        if self.food_name != "alcohol":
            ghests[int(number)-1].order += int(new_order)

class Ghest_over_20(Ghest):
    def __init__(self,number,food_name,age,order):
        super().__init__(number,food_name,age,order)

    def sumup_order(self,food_name,new_order):
        self.order += int(new_order)

    
ghests =[]
N,K = map(int,input().split())

#お客様リスト
for i in range(N):
    number,age = i, int(input())
    food_name,order = "",0
    if age > 20:
        ghests.append(Ghest_over_20(number,food_name,age,order))
    else:
        ghests.append(Ghest(number,food_name,age,order))



#注文リスト
for j in range(K):
    number,food_name,new_order = input().split()
    ghests[int(number) - 1].sumup_order(food_name,int(new_order))

#結果
for ghest in ghests:
    print(ghest.order)

```

時間もないので解答みました。
アルコールOKならfoodが200円引きなの忘れてました。
なのでちょっと書き直します。
initするときsumもリセットしないとだめですね。
他にもメソッドで、foodかsoftdrinkかalcoholかを分けて定義してましたね。
何もしないはpassで定義します。
adultクラスは、
アルコールの有無でTrue／Falseを格納させて、
foodの場合に200円引きさせてましたね。

で、その後、２０歳かそうでないかでクラスを大人クラスか子どもクラスを選んで
配列に直接入れてましたね。。。なるほどです。

書き直しました。

```py
class Ghest():
    def __init__(self):
        #初期化
        self.sum = 0

    def take_food(self, price):
        self.sum += int(price)
    def take_softdrink(self, price):
        self.sum += int(price)

    def take_alcohol(self, price):
        pass
    def get_sum(self):
        return self.sum

class Adult(Ghest):
    def __init__(self):
        super().__init__()
        #初期化
        self.alcohol = False
    def take_food(self, price):
        if self.alcohol:
            self.sum += int(price) - 200
        else:
            self.sum += int(price)
    def take_alcohol(self,price):
        self.sum += int(price)
        self.alcohol = True

N, K = map(int,input().split())
ghests = [None] * N

for i in range(N):
    age = int(input())
    if age >= 20:
        ghests[i] = Adult()
    else:
        ghests[i] = Ghest()

#注文リスト
for _ in range(K):
    number,order,price = input().split()
    if order == "food":
        ghests[int(number)-1].take_food(price)
    elif order == "softdrink":
        ghests[int(number)-1].take_softdrink(price)
    else:
        ghests[int(number)-1].take_alcohol(price)

#結果
for ghest in ghests:
    print(ghest.get_sum())
```

initで、毎回self.numberとか定義を毎回やらないかんのかなとずっと
思い込んでいたのですが、どうやらそうでもないみたいです。
どんな時にinitで定義しないとだめなのかな。そこがまだわからないですね。。。

なかなかクラスのことを理解できず、まだまだ時間がかかりますね。。。
Pythonだけで作る Web アプリケーション(フロントエンド編)Bookの紹介

お疲れ様です。

今日は「Python だけで作る Web アプリケーション(フロントエンド編)」Bookについて紹介いたします。

以前に投稿した記事は削除しました。

下記のbookをご紹介します。

https://zenn.dev/alivelimb/books/python-web-frontend

よろしくお願いいたします。
プログラマーと子育てと子供の勉強（中学入学前後）

# 発端

子供がいるプログラマーであれば気になる話

https://anond.hatelabo.jp/20240304161913

## 要約

### 数学

- 最初は苦手だったが、正負の計算や方程式を理解することで一気に理解が進む
- 一次関数は科学史への興味が効果を発揮し、理解が深まる

### 国語

- 親御さんが読んでいる本を要約させることで理解度を確認

### 英語

- 文法と成り立ちから教えることで、文法構造を理解

### 勉強のやり方

- 定期テスト対策として、学校指定の問題集を2週間前から予習
- インプットとアウトプットの間隔を短くするため、1ページごとに採点・確認・再解を行う
- 問題が解けない原因を言語化させるように指導
- 市販の問題集で補習し、実戦形式の問題は制限時間内に解くように練習

### 学校と塾について
- 学校と教師は微妙
- 塾はなるべく通わせたくなかったが、英語の伸び悩みのため個別指導に通わせた

## 個人的に考える中学入学前後の勉強

### 数学
- 九九ができるかを確認したほうが良い
- 問題文で問われていることを理解していないことが間違いの原因であることが多いので、問題文の意図をマンツーマンで確認する必要がある
- 単純計算問題で点を落としたときに復習をしない。これは、わかっていると思っているから。しかし、わかってはいるけど正解にならないというのは理解度が浅いということを意味する。解決するには朝起きて10分プリントという問題集を毎日やる
- 数検の過去問を5級ぐらいからはじめて、可能であれば受験して、合格することで自己肯定感を高める

<a target="_blank" href="https://www.amazon.co.jp/%25E4%25B8%25AD%25E5%25AD%25A610%25E5%2588%2586%25E9%2596%2593%25E5%25BE%25A9%25E7%25BF%2592%25E3%2583%2589%25E3%2583%25AA%25E3%2583%25AB-%25E8%25A8%2588%25E7%25AE%25971%25E3%2580%259C3%25E5%25B9%25B4-%25E3%2582%25B5%25E3%2582%25AF%25E3%2582%25B5%25E3%2582%25AF%25E5%259F%25BA%25E7%25A4%258E%25E3%2583%2588%25E3%2583%25AC-%25E4%25B8%25AD%25E5%25AD%25A6%25E6%2595%2599%25E8%2582%25B2%25E7%25A0%2594%25E7%25A9%25B6%25E4%25BC%259A/dp/4424636178/ref=sr_1_5?__mk_ja_JP=%25E3%2582%25AB%25E3%2582%25BF%25E3%2582%25AB%25E3%2583%258A&amp;crid=1Y1XZEF5SHZNT&amp;dib=eyJ2IjoiMSJ9.wrMqPGOTeNcHoO0LqEP0ji3-IQCdcjo71vr47u-pEYyfmJZMrdDcuqQbz4tzZeZENSfQQF4GJPQU-O5BwDkz202puZ8KMGgJI5BOjFGxdH3VeDnvcmp_TG6h9vdHamyQkBP2kGBsbvykYJ02SaXnbkvInGcSia9x2NIAoYKPchumCSTVXXBV6442wnKwLXVL3-hcwAjBwTZLHAzezXjyE8iEJloisrNSKzRipRoN0C4iUXq7SKlMNL_Iv-TIUsqDrmeZwibHrz--T6uskTQXxURfVxxMpPGxJTg3DRyoQzQ.tVUl6m5RVPDNRvkLtL8YbcYED2EJL1k-KRf-eas9XaU&amp;dib_tag=se&amp;keywords=10%25E5%2588%2586%25E8%25A8%2588%25E7%25AE%2597&amp;qid=1709616032&amp;sprefix=10%25E5%2588%2586+%25E8%25A8%2588%25E7%25AE%2597%252Caps%252C176&amp;sr=8-5&_encoding=UTF8&tag=amacebi-22&linkCode=ur2&linkId=c8e7138eccfa45c5b6c6d538e35fd2ac&camp=247&creative=1211">中学10分間復習ドリル</a>


### 英語
- 英語でアニメやディズニーやアクションものを見ることで心の壁をとっぱらう
- 学校のワークを何度も解く。テストはワークから出る。

<a target="_blank" href="https://www.amazon.co.jp/gp/video/storefront?&_encoding=UTF8&tag=amacebi-22&linkCode=ur2&linkId=94164f9930322ff21ef96e37786dbde9&camp=247&creative=1211">アマゾンプライムビデオ</a>

### 国語
- 公文に小学校で通って、中学3年までのカリキュラムを終えても、中学のテストは取れない
- 中学の国語のテストは、ワークの中から出るのでワークをやる
- 自分自身を見つめる3年間にするため、自分の考え方をまとめる日記のような文章を書き、第三者が添削


### 受験
- 過去問を解く。同じ問題でも解く。暗記するまで解く
- 一般的な中学生の高校受験は科目を問わず暗記である。数学でさえ暗記科目レベル
- いかに落とすかを考えるようなレベルの高い高校は今回の話では考えていない
- 受験で最も大切なのは勉強をさせることより、勉強をしてこの進路に進みたいという強い欲望。それがないと、いやいや勉強をやらされているだけなので時間も費用も無限に流れていってしまう


### 学校と塾
- 教師は忙しいし、仕事だからやってるだけだから、過度な期待をしない
- 逆に自分が仕事でやっていると考えたら、仕事の大部分を雑務で占められる場合、40人いる生徒一人ひとりの状態と将来に寄り添っている余裕は無いと思う。なぜなら、教師にもプライベート（介護、子育て、自分の人生）が存在するから
- 大手学習塾は行かないほうが良い。なぜなら売上最優で講師は仕事でやっているだけだから
- 塾長が家族経営で10年以上経験している1校だけの学習塾が良い。理由は、塾長もそれで食べてるから、一人ひとりに対して寄り添って、その一人から数年後の受講生紹介まで導けるから。また、家族経営の塾の場合キャパが決まっており、それ以上の募集は不要なので、満員にすれば経営は安定するし、そこに必要なのは一人ひとりへの寄り添いだから


将来国立大学の文系のどこかに滑り込めたら良いなぐらいのレベル感で、子育てと勉強に興味が有る点があればコメントお待ちしております。
Hello Worldからの復習 ～コンストラクタ編～

##### お品書き
+ コンストラクタって？
+ Sample
+ 

---
◆コンストラクタって？
-
今回もメソッド系の復習。
**コンストラクト(construct)**
組み立てる、作成するという英単語。
javaでのコンストラクタはオブジェクトを作成するための特殊なメソッド。

オブジェクトの初期化に使われる特殊なメソッドを
**コンストラクタ**という。

::: note
ルール①：名前がクラスと同じ
ルール②：戻り値を持たない
ルール③：new クラス名(コンストラクタへの引数)←呼び出し側のルール
:::

Sample
-

一般的にメソッド名は最初`小文字スタート`だが、`クラス名と同じにするルールの為、大文字スタート。`
```java:java
class Student{
  Student(String n){ 
  .
  .
  }
  Student(String n, int e, int m){
  .
  .
  }
}
```

オーバーロード編でsetDataというメンバー変数の情報を設定するメソッドを復習したが、


https://qiita.com/tianshandafu894/items/44c587c885fbee947ede

今回はそれをそのままコンストラクタに置き換える。

ちなみに、コンストラクタもメソッドの一種なのでオーバーロード出来る。

```java:java
main( ～ ){
  Student stu1 = new Student("大輔"); //右辺の引数の所がコンストラクタの呼び出しになっている
  Student stu2 = new Student("湊丞", 75, 100);
```
`型名 変数名 = new クラス名(コンストラクタの呼び出し);`

ちなみに、
これまでnew　クラス名()とだけ書いてきて、コンストラクタなんて何も宣言していなかったのに、どう動いてた？
と思うかもしれない。

::: note
コンストラクタを定義していていない場合は、自動で**デフォルトコンストラクタ**(引数、処理なし)が生成される。
(例) Student( ){ }
:::

◆Sample
-
前回のオーバーロードのSampleをベースにSample作成
```java:java
class Student3{
  String name;
  int engScore;
  int mathScore;

  Student3(String n){ //コンストラクタ
    name = n;
  }
  Student3(String n, int e, int m){ //コンストラクタ
    name = n;
    engScore = e;
    mathScore = m;
  }
  void setScore(int e, int m){
    engScore = e;
    mathScore = m;
  }
  void display(){
    System.out.println(name + "さん");
    System.out.println("英語" + engScore + "点・数学" + mathScore + "点");
  }
}

```

```java:java
class StuSample3{
  public static void main(String[] args){
    Student3 stu1 = new Student3("大輔");
    Student3 stu2 = new Student3("湊丞", 75, 100);

    stu1.setScore(90, 80);
    stu1.display();
    stu2.display();
  }
}

```

```cmd:cmd
C:\Java\1>java StuSample3
大輔さん
英語90点・数学80点
湊丞さん
英語75点・数学100点

C:\Java\1>
```
コンストラクタは生成と同時に変数に代入できるため、見やすくなった。
前回までのサンプルだとオブジェクトを生成して値の代入という2ステップがあるため、メンバー変数が設定されていないタイミングが出てしまう。
変数宣言直下にdisplayメソッドを記述すると、中身がない状態で表示されてしまう。
データが空の状態はよろしくないとされている。

それを踏まえてコンストラクタの生成で値の代入が出来るのは、便利でかつ安全だということでよく使われる。

ちなみに、

::: note
自分でコンストラクタを定義した場合は、
デフォルトコンストラクタは生成されない
:::

**stu3をデフォルトコンストラクタとして作成**↓
```java:java
class StuSample3{
  public static void main(String[] args){
    Student3 stu1 = new Student3("大輔");
    Student3 stu2 = new Student3("湊丞", 75, 100);
    Student3 stu3 = Student3(); //デフォルトコンストラクタとして機能するか...

    setScore(90, 80);
    stu1.display();
    stu2.display();
  }
}
```
とするとどうなるか。

```cmd:cmd
C:\Java\1>javac StuSample3.java
StuSample3.java:5: エラー: Student3に適切なコンストラクタが見つかりません(引数がありません)
        Student3 stu3 = new Student3();
                        ^
    コンストラクタ Student3.Student3(String)は使用できません
      (実引数リストと仮引数リストの長さが異なります)
    コンストラクタ Student3.Student3(String,int,int)は使用できません
      (実引数リストと仮引数リストの長さが異なります)
エラー1個
```

無事に怒られましたねW
NestJS7系から10系へのアップグレードではまった話

NestJS7系から10系にアップグレードする際にサービスのDIではまったので備忘。

サービスのDIでトークンが使用できるがその使い方が7系と10系で変わっていた。

7系で利用されていた例

```
@Injectable()
export class SampleService {
  @Inject('MockService')
  private readonly mockService: MockService;
}
```

10系では上記のような例は利用できず以下のエラーが発生していた。
```
Error: Nest can't resolve dependencies of the MockService. Please make sure that the "mockService" property is available in the current context.
```

トークンを指定するためにはドキュメントにあるようにモジュールでトークンにクラスを割り当てる必要がある。
```
@Module({
  providers: [
    {
      provide: MockService,
      useClass: MockServiceImpl,
    },
  ],
})
```

なんか動くからと実装してると急に動かなくなるよという教訓。
Rancher Desktop で Kubernetes を始める

Kubernetes は好きでは無いが仕事で使う事になってしまったので諦めて復習します。

# 準備

今回は [Rancher Desktop](https://rancherdesktop.io/) という Docker 互換アプリで Kubernetes 環境をローカルに作ります。 Rancher Desktop をインストールすると Kubernetes も起動します。あとは、`rancher-desktop` に use-context するとローカルの kubernetes が使えるようです。(ドキュメントが見つからなかった)

```shell
$ kubectl config use-context rancher-desktop
$ kubectl get namespaces
NAME              STATUS   AGE
kube-system       Active   105d
kube-public       Active   105d
kube-node-lease   Active   105d
default           Active   105d
```

# 簡単なアプリをデプロイする。

ここで [Run a Stateless Application Using a Deployment](https://kubernetes.io/docs/tasks/run-application/run-stateless-application-deployment/) の例を試します。

以下のようなファイル deployment.yaml を作って:

```yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
spec:
  type: LoadBalancer
  selector:
    app: nginx
  ports:
    - name: http
      port: 8087 # 公開するポート番号
      targetPort: 80 # Pod のポート番号
```

`kubectl apply` でデプロイします。

```shell
$ kubectl apply -f deployment.yaml 
deployment.apps/nginx-deployment created
service/nginx created

$ kubectl get pod     
NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-86dcfdf4c6-fcwct   1/1     Running   0          21s
nginx-deployment-86dcfdf4c6-lhrxd   1/1     Running   0          21s

$ kubectl get services
NAME         TYPE           CLUSTER-IP      EXTERNAL-IP    PORT(S)          AGE
kubernetes   ClusterIP      10.43.0.1       <none>         443/TCP          106d
nginx        LoadBalancer   10.43.125.223   192.168.5.15   8087:31345/TCP   27s
```

これで http://localhost:8087 にデプロイされています。

`kubectl delete` で削除します。

```shell
$ kubectl delete -f deployment.yaml
deployment.apps "nginx-deployment" deleted
service "nginx" deleted
```

これで何とか Kubernetes の実験を始められるのではないかと思います。

## 参考

* [Kubernetes で 複数の nginx インスタンスを手元の Mac に立ち上げる #Docker - Qiita](https://qiita.com/propella/items/c6e7a45b65b10a4e7e57)
* [Tutorials | Kubernetes](https://kubernetes.io/docs/tutorials/)
SIerのトンチキスクラムについて(2)

# 例えるとこんな感じ

「ひかりあれ」
しかし何もおこら・・いや、40Wの裸電球くらいの光が満ちたような気がする。

# 立ち上げ続き
PM様がなにかいいたそうにこちらを見ている。

技術的なアーキテクトとしてわたくしyamamotodin
業務要件の整理に妙齢のおねーさん
とりまとめとお客様側のPO候補生さんとの課題整理にぱちんかすのお兄さん
インフラであるAWS側の準備に妙齢のおにーさんとやることを決める。

この４人はスクラム経験があり、スクラムの真髄はともかくとして、進め方はわかっていた。
初日か２日目でこの布陣がひけただけでも上等だと思いました。

私が経験則からアーキテクチャをバンバン決めていく。
フロントをSPA, バックエンドをAWS ECSによるコンテナ、DBはなんだっけ・・MySQLかPostgreSQLのどちらかだったと思う多分MySQL。

おにーさんとおねーさんはお客様から可能な限り情報を抜こうをがんばっている。

PM様がなにかいいたそうにこちらを見ている。

取り急ぎやらないといけないのは、２週間以内にいずれくる１０人を超えるスクラムメンバーが開発できるだけのものを用意すること。
スクラムイベントの曜日を決めて、ストーリーやバックログの整理を始める。

私はPCが支給される前からgithubにレポジトリを立ててreadmeを整備したり、CI/CDをどうするかなどを形にしていく。

PM様がPMOを召喚、なにかいうためにこちらに歩いてくる。

「yamamotodin、PMOのヤニカス君だ、よろしくやってくれたまえ」

ごめんほんとにいみがわからないの、ぼくらすくらむやるんですよね？どういうこと？

クソ忙しいから話しかけるのもほんとにやめてほしいんだけどこのPMOとやらをどう扱うかで１時間モメ・・対話が行われる。
ヤニカス君の経歴を聞いたけど、スクラムとかアジャイル開発の経験なし、ガッチガチのウォーターフォール人間。

とりあえず今クソ忙しいから無理、どうしてもなんかしたいならとりまとめやってるおにーさんと協議してってことにして解散。

40Wの電球の光、揺らいで消えそうです・・
AtCoder Beginner Contest 342の参戦記録

RubyでAtCoderに参戦した記録です。
AB2完で、C問題はコンテスト終了後に解説を見てからコードを書きました。

## [ABC342 A Yay!](https://atcoder.jp/contests/abc342/tasks/abc342_a)
ある1文字を除いてすべて同じ文字で構成される文字列Sの中で、他の文字と異なる1文字は前から何文字目かを出力する問題です。
```Ruby
s = gets.chomp.chars  # 受け取った文字列sをcharsメソッドで1文字ずつの配列にする
h = s.tally  # 各アルファベットの出現頻度をHashにまとめる
ans = h.key(1)  # Hashの値が1のもののキーとなる文字をansに代入
puts s.index(ans) + 1  # ansの文字列(配列)sの中での登場箇所インデックス + 1を出力
```



## [ABC342 B Which is ahead?](https://atcoder.jp/contests/abc342/tasks/abc342_b)
並んでいる人の番号が与えられ、続くクエリで指定される2つの番号のうち、前に並んでいる人のほうの番号を出力する問題です。
```Ruby
n = gets.to_i
array=gets.split(" ").map(&:to_i)
q = gets.to_i
query = []
q.times do
	query << gets.split(" ").map(&:to_i)
end

query.each do |qr|
  if array.index(qr[0]) < array.index(qr[1])
    puts qr[0]
  else
    puts qr[1]
  end
end
```
最初の提出ではquery.eachのパラメータを1つにして添字を指定していましたが、下記のようにパラメータを2つにした方がすっきり記述できるなと後で気づきました。
```Ruby
query.each do |a,b|
  if array.index(a) < array.index(b)
    puts a
  else
    puts b
  end
end
```



## [ABC342 C Many Replacement](https://atcoder.jp/contests/abc342/tasks/abc342_c)
文字列Nに対し、Q回の操作を行っていく問題ですが、NもQも最大で10**5くらいまでいくとのことで、一回ずつ操作結果を確認しているとTLEとなります。
解答時間内はTLEを解消することができず、撃沈しました。。
```Ruby
# TLE解答
n = gets.to_i
s = gets.chomp
q = gets.to_i
query = []
q.times do
	query << gets.split(" ")
end

query.each do |q|
  if !s.include?(q[0])
    next
  elsif q[0] == q[1]
    next
  else
    s.gsub!(q[0],q[1])
  end
end

puts s
```
### 方針１：クエリの結果をHashにまとめる
全クエリの終了後にアルファベットの各文字がどの文字になるかをHashにまとめ、最後に文字列Nを置き換えします。
```Ruby
n = gets.to_i
s = gets.chomp
q = gets.to_i
query = []
q.times do
	query << gets.split(" ")
end

alpha = [*"a".."z"]
hash = {}
alpha.each do |e|
  hash[e] = e
end
query.reverse_each do |c,d|
    hash[c] = hash[d]
end

puts s.gsub(/./,hash)
```
- クエリをHashにまとめる際は``reverse_each``で最後のクエリからみていきます。というのも実際の操作では、後に行われる操作が前の操作を上書きしていくことになるからです。
例えば「"a"=>"b"」という操作が出てきたとき、それよりも後のクエリで「"b"=>"c"」という操作があるなら、最終的に「"a"=>"c"」ということになります。これを実現するための記述が``hash[c] = hash[d]``です。
- String#gsubでreplaceとしてHashを指定できることを初めて知りました。第一引数には置き換えする文字列パターンを指定しますが、今回はすべてのアルファベットの置き換え結果をhashに用意してあるので、全文字を置き換え対象とする``/./``としています。

### 方針2："abcdefghijklmnopqrstuvwxyz"という文字列でクエリ結果を検証する
```Ruby
n = gets.to_i
s = gets.chomp
q = gets.to_i
query = []
q.times do
	query << gets.split(" ")
end

before = [*"a".."z"].join
after = [*"a".."z"].join
query.each do |c, d|
  after.gsub!(c,d)
end
puts s.tr(before,after)
```
クエリの数が多くても、a~zの26文字のみであればすべて検証してもTLEにはなりません。

## おわりに
C問題はいつもTLEになってしまい、解決法が考えつかないのが悔しいです。引き続き過去問を解くなどして効率の良い方法や考え方の引き出しを増やしていきたいと思います。

## 参考リンク
https://docs.ruby-lang.org/ja/3.3/method/String/i/gsub.html
SIerのトンチキスクラムについて(1)

# 導入
♪遠い昔の話で　新しいこの現場が　今アサインされて僕らの胸 不安に打ち震えているよ

# 何をするのか
某キャリアの窓口における機種変更等の手続きを受付るためのUIとバックエンドを作成してリリースし、もういいと言われるまで運用する。

商流としては某キャリアから直接某SIerが受託しています。

関連会社や初動で4人+(なぞの３人)そこから11人(+なぞの4人)を送り込んでスクラム(Scrum of Scrums)させようという素晴らしいお考えです。

やりたいことじたいは今だったらwebでポチポチで終わる話ですがコロナ前でして、なぜかそこにこだわっている人が居た。

そう、それはめっちゃお金持ってる真のPO(Product Owner)である。

# なぜやるのか
窓口における負担を減らしたい！そうやAIでうまいことやってRPAも絡めてウッハウハやでー（注意：投稿者の独自解釈があります）、みたいなことを考えていたように思えます。
それを人がいっぱいいる場所で言っちゃったからやるんですねー

# どうして？
どうもこのキャリアさん、社内のエンジニアリングについて１０年くらい外部からの勢力を受け入れず、その結果わけがわからなくなったため外の血を入れるという試みをこの年から始めた模様。

その時私は「え、SIerとかベンダーの力を借りずに独自でやってたんすか？」と思いました。
そう思ったんですが思い知るのはこれからですじごくのはじまりです。

# 最初の１ヶ月が一番おもしろい
まだ海と大地が分かれておらず、混沌としてスクラムを回すためのチームすら発足していない立ち上げの時期です。

## 要件定義について
さてまずお客様が**まともな要件定義をするノウハウも能力も時間もないため**それらがSIerサイドに全部、すべて、オールオブオール丸投げされる。

「待って、要件定義ってどういう形でやってもいいけど、なにをどう実現するか決めるものだよね？なんで丸投げなの？　この現場に億単位のお金投じるんだよね？　どうして？」

私の頭の中、ハテナマークしか浮かびません。

聞くところによると、最初の方はSIer側からウォーターフォール的な開発を提案したそうだけど、全てを最初から決めきることはできないとのことで、アジャイルのスクラムが採用されたと。
絶対好き放題仕様変更できると勘違いしてるよねｗｗｗｗｗｗｗw草しか生えん

## 立ち上げについて
さて、配置当日に言われた我々の雇い主、SIerのPM様からのありがたくて涙が出ちゃうお言葉を意訳します。

**「yamamotodin..お前らに２週間やるから開発できる状態にしろ。」**

え・・今スクラムマスター候補の3人と、外部支援要員しかいないんですけど？

そもそもスクラムなのにPMってなんすか、僕PM様って肩書おかしくない？

仕方ないので今居る人のスキルを把握して即席のチームをビルドする。というか私達しかこの世界に居ないと思った方が良い。面構えの違うメンツを紹介しよう。

現場さんチーム

A. わたくし、自称野良の傭兵yamamotodin(アラフォー)。スクラム経験はメンバーとしてあり、スクラムマスター３５の仕事を闇夜の灯火として掲げる理想主義者
B. 年齢を聞いてはいけないおねーさんで業務の鬼
C. 自分のことをパチンカスと言い土日は台風以外は朝並ぶマネジメント見習いのお兄ちゃん
D. SIerのプロパーでアーキテクトのイケメン　おじさんとおにーさんどっちで呼べばいいか悩ましいお年頃。

A,B,Cがスクラムマスター、Dの人がスクラムの外から支援する要員。

事あるごとに御高説を垂れる謎が謎を呼ぶチーム

E. PM様
F. スクラムコーチ様
G. PMO様

一体何が始まるんでしょうね・・・・・・・・・・・・・
R3を導入する際の注意事項

**本記事はR3を導入しようとしたときにやらかしたことをまとめた記事です！**
## はじめに
巷で話題のR3を導入しようかと思い、Unityでアレコレしてたら2回ほどやらかしてしまい、それについての記事がなかったためまとめたのが本記事になります。R3の詳しい説明は以下の記事がとても参考になると思います。
https://qiita.com/toRisouP/items/4344fbcba7b7e8d8ce16
またR3の公式ドキュメントはこちらです。
https://github.com/Cysharp/R3
## 導入について
R3は「コアモジュール」と「Unityプラグイン」という2つのモノを入れる必要があります。このうち「Unityプラグイン」の方はUnityPackageManagerからgitURLを使うことで簡単にインストールすることが出来ますが「コアモジュール」の方は少しばかり手間がかかり、自分も導入する際に色々とやらかしてしまいました。この「コアモジュール」をインストールするにはNuGetを利用する必要があります。R3公式では以下のNugetForUnityを利用することが推奨されています。
https://github.com/GlitchEnzo/NuGetForUnity
## やらかしその1
まず自分がR3を導入する上でやらかしたのがNugetForUnity導入後の2つのDefaultAssetを別フォルダに移動させてしまったことです。NugetForUnityを入れるとAssetsフォルダ直下に以下の2つのDefaultAssetが生成されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/7af3a06f-238a-b1d3-35d5-70bfbb8da1a6.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/653806d2-c0d7-97ec-61df-b27a3c49ac25.png)
（NuGet・packagesの2つが生成されたものです）
自分はこの2つを別のフォルダに移行し、作業をしたのですがUnityを再起動した際に1枚目画像のpackagesの中身がすべて消え、フォルダに移行したNuGet・packagesとは別にAssetsフォルダ直下にNuGet・packages再び生成されてしまいました。そのため1つ前のコミットに戻し、Assetsフォルダ直下にNuGet・packagesがある状態に戻したところ無事に再起動が出来たので**この2つは動かしてはいけないことが分かりました。**
## やらかしその2
上の問題に直面した際「もしかしてUnityプラグインのみ入れても動くんかな？」という疑問が浮かんでR3→NugetForUnityの順番でUnityにインストールした際、問題は起きました。もちろんUnityプラグインのみのインストールでは大量のエラーが発生してR3は動きません！そのためNugetForUnityを後から入れた結果、通常ならUnityの上部にNuGetが表示されるのですが、それが表示されずコアモジュールを導入できなくなってしまい結果Unityプラグイン導入前の状態に戻す羽目になりました。（github使ってたので大した痛手にはならず…）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1915044/847a24d1-7a30-0c0a-1b17-7020fa46ebd2.png)
## まとめ
①生成されたものを勝手にフォルダ分けしない！！
②インストールの順番は公式ドキュメントに従う！！
当たり前のことですが改めてこの2つの大切さが身に沁みました。
ただフォルダ分けはしたいのでそこはこれから深堀したいと思います。
https://github.com/GlitchEnzo/NuGetForUnity/pull/619
上のPRを読むと現状フォルダ分けが出来ず、分けれるように改善しているっぽいです。
Playwright で E2E テスト（VSCode Extension を使って自動生成）

## この記事について
既存プロジェクトへの Playwright の導入方法をまとめています。

より具体的な使い方については以下もご参考ください！

https://zenn.dev/tomoeine/scraps/2ef3892af5784b

## はじめに
初めて Playwright を使ってみたのでまとめておきます！
今回は既存のプロジェクトに追加しました。

### 環境
- Vue.js
- TypeScript
- yarn
- GitHub Actions
- VSCode

### 選定理由
既存のアプリケーションなので、なるべく手間をかけずに導入したい・・・
ということで、定番の Cypress ではなく自動生成が強みっぽい Playwright にしました。
（今は Playwright の方が定番化しているのかも？）

## インストール
公式の手順にしたがって追加します
https://playwright.dev/docs/intro

```
yarn create playwright
```

いくつか質問をされるので、以下のように回答しました。
```
Where to put your end-to-end tests? : tests （デフォルト）
Add a GitHub Actions workflow? (y/N) : true （yを入力）
Install Playwright browsers (can be done manually via 'yarn playwright install')? (Y/n) true
```

ファイルを見てみると `tests` `tests-examples` ２つのディレクトリができていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/1d360517-cad8-f12e-ea99-6b911c42bdc3.png)

GitHub Actions のワークフローも生成されたようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/8eec83be-02ab-a14a-116e-15c4a3718f09.png)


さっそくサンプルテストを実行。

```
npx playwright test
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/e25c6764-d57b-99a4-7dbd-2ebdb1393f46.png)

うまく動いているようです。
`npx playwright show-report` を実行すると、ブラウザで詳しい結果が表示されました。

## VSCode の拡張機能を追加
VSCode を利用しておくなら、入れておくと便利です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/369bdc9e-7717-6265-a5ff-c9886bf768c0.png)


## テストを生成してみる

ここでは VSCode の拡張機能を使う方法を紹介します。
（拡張を使わなくても、 `npx playwright codegen` コマンドで同様のことができそうです。
https://playwright.dev/docs/codegen-intro ）

サイドバーから test タブ（ビーカーのアイコン）を開くと「PLAYWRIGHT」が表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/cb5e035d-5988-cba4-35e8-682078ed7f16.png)

「Record new」をクリックすると、新しいテストファイルが作成され、記録用の Chromium が起動します。
テストしたいURLを入力して

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/15e2c29c-d455-2874-7c62-326ee8480023.png)

テストしたい操作を実際に行い、期待した動作になることを確認します。
（今回はメールアドレスとパスワードを入力し、「ログイン」ボタンをクリックしました）

期待通りの動作（ex: 画面遷移）になったことを確認したら、
 `Assert Visible` アイコン（真ん中の目のマーク）をクリックし、
 検証したい項目をクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/998c1abb-90a2-a345-fac7-67d15e0c8ee4.png)

最後に、 `Record` アイコン（左の赤い●）をクリックすると、以下のようなテストが生成されているのを確認できました。

```TypeScript
import { test, expect } from '@playwright/test';

test('test', async ({ page }) => {
  await page.goto('http://localhost:4000/signin');
  await page.getByPlaceholder('メールアドレス').click();
  await page.getByPlaceholder('メールアドレス').fill('user01@example.com');
  await page.getByPlaceholder('パスワード').click();
  await page.getByPlaceholder('パスワード').fill('User01password');
  await page.getByRole('button', { name: 'LOGIN' }).click();
  await expect(page.locator('.page-header-container')).toBeVisible();
  await expect(page.getByText('ログインしました')).toBeVisible();
});
```

実行ボタン（▷）を押してテストを実行してみると、無事通ったようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/135266/e1e94487-eef6-f444-60cf-d5ae3423c60a.png)

あとはひたすらいろんなパターンで操作してテストを追加していくのみ！
思った以上に簡単でした。
パーペチュアルってなんぞ

ライセンスの話をしていたとき、「パーペチュアル」って言葉がいきなり飛び出してきました。
なんじゃそりゃとなったので調べた備忘録です。


# パーペチュアル
パーペチュアル（perpetual）とは、"永続する、永久の"という意味。
パーペチュアルライセンスとは、一度購入すると永続的に使用できるライセンスのこと。
原則追加費用なしで使うことができる。
最初の購入後は、関係は終了するか、保守契約に移行する。

逆の言葉はサブスクになる。

# まとめ
パーペチュアルは、サブスクの反対。
一度購入するとずっと使えるよってやつ。

# 参考
https://tooljp.com/windows/chigai/html/Lisense/perpetual-vs-subscription.html

https://cpl.thalesgroup.com/ja/software-monetization/perpetual-license

> (余談)　パーペチュアルって調べると、腕時計で有名なロレッ◯スとか出てきて、最初めっちゃ混乱しました。
f.text_field について

クレジットなどで購入機能を付ける際、クレジット番号など記載するマスを作りたい場合に

```ruby:
<%= f.text_field :number, class:"input-default", id:"number-form"%>

```

とする。

尚f.text_fieldの後ろは任意の名前をつけて、class,idの順で記載
HiltViewModelで始めるAndroidの依存性注入のお話

# はじめに
最近のAndroidアプリのアーキテクチャ設計において、依存性注入(DI)は必須のパターンとなっています。特に、ViewModelを使った設計ではDIがさらに重要な役割を果たします。**Googleが提供するHiltは、AndroidのためのDIライブラリとしてこの問題をスマートに解決してくれます。**
今回はHiltViewModelを使用して、ViewModelのDIを簡単に行う方法を紹介します。

# Hiltとは？
Hiltは、DaggerをベースにしたAndroid用の依存性注入ライブラリです。設定が簡単で、アノテーションを利用するだけで依存性の管理が可能になります。
`@HiltViewModel`アノテーションを使用すると、ViewModelがHiltの管理下に入り、必要な依存関係がコンストラクタ経由で自動的に注入されます。
使用するメリットとしては以下のことが挙げられます。

:::note info
- ViewModelのテストが容易になること
- 依存性の管理が明確になりとコードの可読性が向上すること
- コンパイル時に依存性の解決を行うため、安全性が高いこと
- 簡単に使用できること
:::


# アーキテクチャ図
サンプルとして、実際に業務で構築しているAndroidアプリのアーキテクチャ図の簡易版を置いておきます。
なんとなくのイメージがわかると思います。
![android.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1576629/9f1ee96f-b66e-bfad-e10a-0bcff306e899.png)

# 実装方法
まず、プロジェクトの`build.gradle`にHiltの依存性を追加します。
```kotlin
// hilt-android-gradle-plugin
// See https://developer.android.com/training/dependency-injection/hilt-android?hl=ja
implementation("com.google.dagger:hilt-android:2.50")
```

次にApplication.ktに`@HiltAndroidApp`アノテーションをつけます。
```kotlin
@HiltAndroidApp
class MyApplication : Application() {
    // ...
}
```
ViewModelに`@HiltViewModel`アノテーションを付け、依存関係をコンストラクタで注入します。
```kotlin
class MainViewModel @Inject constructor(
    private val repository: MainRepository
) : ViewModel() {
    // ...
}
```
使用する際は、`@Composal`からは以下のように呼び出します。
```kotlin
@Composable
fun MyScreen(
    viewModel: MainViewModel = hiltViewModel(),
)  {
    // ...
}
```
# 終わりに
上記のようにHiltViewModelを使うことで、AndroidアプリにおけるDIが簡単に実装できます。コードが簡単になると、保守性やテストのしやすさも向上するのでいいことづくめですよね。この記事が誰かのAndroidアプリのコードを綺麗にすることを願ってます。
これからもGoやKotlinの記事を投稿していこうと思っているので、読んでいただけたら嬉しいです。

# 参考記事
https://developer.android.com/training/dependency-injection/hilt-android?hl=ja#hilt-and-dagger

https://developer.android.com/training/dependency-injection/hilt-jetpack?hl=ja

https://dagger.dev/hilt/view-model.html
【AtCoder C++】-B- ABC090 Palindromic Numbers

## 学習用 -B- Palindromic Numbers
https://atcoder.jp/contests/abc090/tasks/abc090_b
~~~c++
#include <bits/stdc++.h>
using namespace std;

int main(){
  int A,B;
  cin >> A >> B;
  int count = 0;
  //A~Bまでのループ
  for (int i = A; i <= B ;i++){
    //iを取得して、string型に変換
    string A_str = to_string(i);
    //反転したiを取得
    string A_rev_str = A_str;
    reverse(A_rev_str.begin(), A_rev_str.end());
    //if比較してcount
    if(A_str == A_rev_str){
      count++;
    }
  }
  cout << count << endl;
}

// 31415 92653入力例
// 612出力例
//回文が何個か

~~~
難しかった...。解説をGPTに頼んで、その方針に従ってやりました！
最初はforの多重ループで挑戦しようかと思っていました。
アホなわたしA~Bまでのループをして、A内でもforループして、index[i]==index[-i]みたいなやり方でできないかなと試していたんですけど、混乱して止めました。

なので今回は、A~Bまでのループで、Aを取得したらstring型に変換して、そのreverseされたものも関数で用意して、それをif比較することで回文かどうかをチェックしました。

**いい解法で解いている記事見つけました！**
https://qiita.com/RoadLynton/items/e7ebc6c16c78829489ef
string型にしたらat()を活用すれば、index[i]==index[-i]こんなことしなくてよかったです。。。
今回5桁の整数なので、10000の位==1の位(at(4)==at(0)) と 1000の位== 10(at(1)===at(3))の位に気づけなかったです。。参考になりました！
SDKとは？APIとの関係

# はじめに

"SDK" というものをご存知でしょうか。

例えば、LINEのMessaging APIに登場します。

https://developers.line.biz/ja/docs/messaging-api/line-bot-sdk/

> LINE Messaging API SDKには、ライブラリ、ツール、およびサンプルが含まれています。SDKを使えば、Messaging APIを組み込んだボットアプリの開発を簡単に始めることができます。

つまり、"SDK" を使用すると、簡単にLINE Botを開発できるようです。

<font color="Orange">SDKとは？</font>
# SDKとは？

**SDK** は、**Software Development Kit** （ソフトウェア開発キット）の略称です。

なるほど、開発におけるツールセットを表すのですね。

先ほどのLINE Botにおいては、「Messaging APIのSDK」と言えそうです。

<font color="Orange">APIとSDKの違いは？</font>

# APIとSDKの違いは？

API
- **Application Programming Interface**（アプリケーションとプログラムをつなげる窓口）
- ソフトウェア間で情報をやりとりするためのルール

SDK
- **Software Development Kit** （ソフトウェア開発キット）
- 特定のプログラムを作成するために必要なツールやライブラリの集まり
- 多くの場合、APIを含む
## 料理に例えてみる

API：調理器具（包丁・鍋・・・）
SDK：調理器具**セット**

<font color="Orange">こだわりのある中級者以上の人は、自分で「調理器具」を選定し、自分に合った器具を使用します。</font>

<font color="Orange">しかし、初心者や、ただ「料理をしたい」人にとっては、「調理器具セット」を使うことが推奨されるでしょう。</font>
少ない手間で、簡単に料理を作ることができます。

彼ら（初心者）に「調理器具の知識」は「あればよいが、なくても問題ない」ものです。
<br>

SDKとAPIも同様のことが言えるでしょう。

初心者や、ただそのアプリケーションの機能を使いたい人にとっては、
「どんなAPIで、どうコードを書くべきかの知識」は「あればよいが、なくても問題ない」ものです。
それよりも「簡単に自分のアイデアを試し、実装したい」というのが本音です。

そのニーズに、「セット」であるSDKが合致します。
# おわりに

APIの説明を`アプリケーションとプログラムをつなげる窓口`としたことや、調理器具の例えはSDKとAPIのすべての面を説明できてはいないかなと思います。
ただ、現状の理解では大まかには正しいと考えています。

より良い説明や例えがありましたら、コメント💬いただけると嬉しいです！
EC2でsystemdによるサービス化で詰まった件

Spring bootで作成したWebアプリをEC2にデプロイしたが、systemd にサービス登録して起動するとエラーになり起動しない。

でも手動でコマンドをたたくと起動する・・・なぜ？


sudo vi /usr/lib/systemd/system/~.service を下記の通り作成
```
[Unit]
Description=[Webアプリ名]
After=syslog.target

[Service]
User=ec2-user
ExecStart=/usr/bin/java -jar /home/ec2-user/app/[Webアプリ名]-0.0.1-SNAPSHOT.jar
SuccessExitStatus=143

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

systemd再読み込み, サービス開始, サービス状態確認
```
sudo systemctl daemon-reload
sudo systemctl start [サービス名]
sudo systemctl -l status [サービス名]
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/ae582cb8-efd2-dc9e-8e3f-39d10e6e5b66.png)
エラーになる

手動で起動すると普通に動作する
```
java -jar /home/ec2-user/app/[Webアプリ名]-0.0.1-SNAPSHOT.jar
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/b9e30155-b917-a85a-103b-501039e9fb1f.png)

どうやらDB接続関係でエラーッポイ

DBはH2をファイルベースで使用しているため、DBファイルの読み書き関係な気がする。

手動で起動した時下記のファイルが作成されていた。
```
/home/ec2-user/database.mv.db
```

このファイルに権限をとりあえず与えてみる
```
sudo chmod 777 /home/ec2-user/database.mv.db
```

結果、状況は変わらずエラー

実行ステータスを見比べてみると

```
手動
(/home/ec2-user/app/[Webアプリ名]-0.0.1-SNAPSHOT.jar started by ec2-user in /home/ec2-user)

自動
(/home/ec2-user/app/[Webアプリ名]-0.0.1-SNAPSHOT.jar started by ec2-user in /)
```

作業ディレクトリが違う？

sudo vi /usr/lib/systemd/system/~.service を下記に変更
```
[Unit]
Description=[Webアプリ名]
After=syslog.target

[Service]
User=ec2-user
ExecStart=/usr/bin/java -jar /home/ec2-user/app/[Webアプリ名]-0.0.1-SNAPSHOT.jar
WorkingDirectory=/home/ec2-user/app ←作業ディレクトリ追加
SuccessExitStatus=143

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

```
sudo systemctl daemon-reload
sudo systemctl start ~.service
sudo systemctl status ~

Active: active (running) since Tue 2024-03-05 12:05:47 JST; 11s ago
```
問題なく稼働した！

EC2のアドレスにアクセスしてみる。
```
http://[EC2パブリックIP]:8080
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3517045/1196023e-f037-f934-db06-946e69c5c6d9.png)

問題なく表示された。
原因はおそらく、作業ディレクトリが [ / ] となっていたため、DBファイルを出力しようとしてもできずにエラーとなっていたっポイ。

今回の反省は、作業ディレクトリはきちんと設定する & アプリ起動時に作成されるファイルの作成先は認識しておくか決めておく。
【AtCoder】ABC074- Collectiong Balls

## 学習記録用 -B- Collectiong Balls ABC074

https://atcoder.jp/contests/abc074/tasks/abc074_b
~~~c++
// 2 N
// 9 K
// 3 6 x1,x2...

// 12
#include <bits/stdc++.h>
using namespace std;

int main () {
 int N,K,X;
 cin >> N;
 cin >> K;
 int sum = 0;
 for (int i = 0; i < N; i++){
    cin >> X;
    int A = abs(X - 0);//(絶対値つけたい)
    int B = abs(X - K);//(絶対値つけたい)
    if(A<=B){
      sum += A*2;//(+=でないと、forループ更新のたびにsumが蓄積されない)
    }else{
      sum += B*2;
    }
 }
 cout << sum << endl;
 
}
~~~
sum = A*2 / sum = B*2を最初していて、時間がかかりました！
Twelve-Factor Appの項目を一言にまとめる

https://12factor.net/ja/

皆さん、抽象化好きですよね。抽象化するのはとても難しいけどめちゃちゃ大事ですしコミュニケーション能力にもかかわるところです。でも具体ももってないのに抽象すると"ITコンサル風"になるので気を付けなければいけないです。
会社でTwelve-Factor Appの勉強会（なのか？）を行った。このサイトを見てただの抽象的な概念の読み合わせがあり、**WebアプリやSaasはこう作りべきと抽象的に書かれているもの**を淡々と読んでいくが、確かに大事なことが書かれてるんだけどただ読み流しなだけでみんな本当に理解してるのか？と感じたので、一瞬で理解できるよう一言でまとめて概念を理解してスッキリしようと思います。
あと、2012年に提唱されて少し古いので、すでにクラウドを扱う上での考慮を加えたBeyond the Twelve-Factor App(2016年)があるので長いしわかりずらいので一言にする。間違い指摘は歓迎します。

https://tanzu.vmware.com/content/blog/beyond-the-twelve-factor-app

### 1. One codebase, one application
１つのプロジェクトに１つのリポジトリにしようね。

### 2. API first
APIのコアな設計を固めてから開発しようね。

### 3. Dependency management
依存ライブラリは管理しようね

### 4. Design, build, release, and run
設計、開発、運用、手順をはっきりさせようね

### 5. Configuration, credentials, and code
設定/環境情報はコードには書かないでね

### 6. Logs
ログはちゃんと取るようにしようね

### 7. Disposability
サクッと起動、サクッと停止できるようにしてね

### 8. Backing services
外部サービス特にDBとかバックサービスは簡単に切り替えられるようにしようね

### 9. Environment Parity
どの環境でも同じように動くようにしようね

### 10. Administrative Processes
管理タスクはラクにできるようにしようね。管理画面作るといいよ

### 11. Port Binding
アプリはポート単位に分けると毎回サーバー構築しなくて済むから効率いいよ

### 12. Stateless Processes
情報はバックサービスで保持しとけ、ステートレスにしとけばリソース追加と削除が簡単になるからいいよ13につながるよ

### 13. Concurrency
12にすることで水平にリソース拡張できるから複数の同時並行でインスタンスを起動させるとかで役立つよ

### 14. Telemetry
パフォーマンスとかどのリソースが使われてるとかちゃんと見れるようにしようね

### 15. Authentication and Authorization
どこの誰が入っていいかちゃんと決めとこうね。


### 感想
言うまでもない当たり前なこともあるけど確かにそうだけど要件によってはそうじゃないこともある。例えばOne codebase, one applicationはこれに限ったことじゃないし、モノレポで管理する方が嬉しい場合もある。あくまで基本的な考え方の材料として、じゃあ私のPJはそれが最適か？と項目別に照合する材料にすればいいなと思いました。