OmniAICreator/Qiita-1.07M huggingface dataset:
Kotlinの文法の基礎（Swiftとの比較）

# はじめに

いままで仕事でSwiftしか使ってこなかったですがAndroidもやることになったので,Swiftと比較しながら調べてみました。

## 1. 変数と定数

### Kotlin
```kotlin
val constant: Int = 10 // 定数
var variable: Int = 5 // 変数
```

### Swift
```swift
let constant: Int = 10 // 定数
var variable: Int = 5 // 変数
```

## 2. 関数

### Kotlin
```kotlin
fun add(a: Int, b: Int): Int {
    return a + b
}
```

### Swift
```swift
func add(a: Int, b: Int) -> Int {
    return a + b
}
```

## 3. クロージャ

### Kotlin
Kotlinのラムダ式は、無名関数やクロージャに相当します。
```kotlin
val sum: (Int, Int) -> Int = { a, b -> a + b }
println(sum(5, 3)) // 8
```

### Swift
```swift
let sum: (Int, Int) -> Int = { a, b in
    return a + b
}
print(sum(5, 3)) // 8
```

## 4. `if`文

### Kotlin
```kotlin
val max = if (a > b) a else b
```

### Swift
```swift
let max = (a > b) ? a : b
```

## 5. `when`文（Kotlinの`switch`に相当）

### Kotlin
```kotlin
when (x) {
    1 -> println("x is 1")
    2 -> println("x is 2")
    else -> println("x is not 1 or 2")
}
```

### Swift
```swift
switch x {
case 1:
    print("x is 1")
case 2:
    print("x is 2")
default:
    print("x is not 1 or 2")
}
```

## 6. クラスとオブジェクト

### Kotlin
```kotlin
class Person(val name: String, var age: Int) {
    fun introduce() {
        println("My name is $name and I am $age years old.")
    }
}

val person = Person("Alice", 25)
person.introduce()
```

### Swift
```swift
class Person {
    var name: String
    var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func introduce() {
        print("My name is \(name) and I am \(age) years old.")
    }
}

let person = Person(name: "Alice", age: 25)
person.introduce()
```

## 7. Nullable型

### Kotlin
Kotlinでは、`null`を扱うためにNullable型があります。
```kotlin
var name: String? = null
name = "Bob"
```

### Swift
Swiftでは、オプショナルを使用して`null`を扱います。
```swift
var name: String? = nil
name = "Bob"
```

## 8. ラムダ式の引数

### Kotlin
```kotlin
fun calculate(a: Int, b: Int, operation: (Int, Int) -> Int): Int {
    return operation(a, b)
}

val result = calculate(5, 3, { x, y -> x + y })
```

### Swift
```swift
func calculate(a: Int, b: Int, operation: (Int, Int) -> Int) -> Int {
    return operation(a, b)
}

let result = calculate(5, 3) { x, y in x + y }
```

## 9. 拡張関数

### Kotlin
```kotlin
fun String.addExclamation() = this + "!"
println("Hello".addExclamation()) // Hello!
```

### Swift
```swift
extension String {
    func addExclamation() -> String {
        return self + "!"
    }
}

print("Hello".addExclamation()) // Hello!
```
cookieに有効期限をつける

# sessionとは何か？
https://qiita.com/masatom86650860/items/3ad9a98a990aea4434d0

# 有効期限をつけてみる
>3.5.15 ActionDispatch::Session::CookieStore
セッションをcookieに保存する役割を担います。config.session_storeの値を変更すると別のミドルウェアを使えます。

https://railsguides.jp/configuring.html#rack-methodoverride:~:text=3.5.15%20ActionDispatch%3A%3ASession,%E4%BD%BF%E3%81%88%E3%81%BE%E3%81%99%E3%80%82

>Because CookieStore extends Rack::Session::Abstract::Persisted, many of the options described there can be used to customize the session cookie that is generated. For example:
>```
>Rails.application.config.session_store :cookie_store, expire_after: 14.days
>```
>would set the session cookie to expire automatically 14 days after creation. Other useful options include :key, :secure, :httponly, and :same_site.

https://api.rubyonrails.org/classes/ActionDispatch/Session/CookieStore.html#:~:text=Because%20CookieStore%20extends,%3Asame_site.

# 感想
色々不十分なところはあるけどこれから頑張ろう
RPCエンドポイントを使ってgethのeth_getBalanceメソッドを呼び出す

# テーマ設定
RPCノードを使ってgethのeth_getBalanceメソッドを呼び出す処理を実装してみる。

# 前提環境
+ Node.js がインストールされている。
+ axios ライブラリがインストールされている。

+ RPCエンドポイントを取得（無料）
https://cabinet-node.com/ja/docs/user-guide/create-access-token

### axiosのインストール
```bash
npm install axios
```

# 実装
以下の内容でeth_getBalance.jsファイルを作成してください。
 ```js
const axios = require('axios');

// RPCエンドポイントを設定
const rpcUrl = 'https://gateway-api.cabinet-node.com/{access_token}';

// eth_getBalanceメソッドを使って指定アドレスの残高を取得する関数
async function getBalance() {
    const data = {
        jsonrpc: '2.0',
        method: 'eth_getBalance',
        params: ['WALLET_ADDRESS','latest'], // set target wallet address
        id: 1
    };

    try {
        // axiosを使ってRPCリクエストを送信
        const response = await axios.post(rpcUrl, data);
        
        // 残高を取得（Wei単位で返される）
        const balance = response.data.result;

        console.log(`Current Balance: ${balance}`);
    } catch (error) {
        console.error('Error fetching balance:', error);
    }
}

getBalance();
 ```

 # 実行
 
  ```
node eth_getBalance.js
  ```

 
### 結果の例

```
Current Balance: ***
```
余剰演算（モジュロ演算）を使用した配列の循環（クリックの度に画像を切り替える）

## 余剰演算（モジュロ演算）とは？
配列などのインデックス番号を指定したとき、配列の数を超える整数を指定されても、再び「0」に戻り、配列を循環するように番号を取得できる。

## 参考コード
以下、Reactのコンポーネント。
画像をクリックするたびに、配列内の画像が切り替わる処理を実装している。

```jsx
const TestComponent = () => {
  const imgArray = [imgUrl01, imgUrl02, imgUrl03, imgUrl04, imgUrl05]
  const [current, setCurrent] = useState(0)
  
  const onChangeImage = () => {
	  setCurrent((prev) => (prev + 1) % imgArray.length)
  }
  
  return (
		 <div>
			 <img src={imgArray[current]} />
		 </div>
  )
}
```

余剰演算（モジュロ演算）は、ある数を別の数で割った余りを返す演算。
今回のケースでは、`imgArray.length`で配列の長さ（ここでは5）を使用する。

クリックされるたびにonChangeImage関数が実行され、currentの状態が更新される。

```jsx
setCurrent((prev) => (prev + 1) % imgArray.length)

// set関数内で行われている計算
// (0 + 1) % 5 = 1 % 5 = 1 … current = 1
// (1 + 1) % 5 = 2 % 5 = 2 … current = 2
// …
// (4 + 1) % 5 = 5 % 5 = 0 … current = 0（配列の最初に戻る）
```

## 参考記事
https://tomosta.jp/2019/05/%E5%89%B0%E4%BD%99%E7%AE%97%E3%82%92%E4%BD%BF%E3%81%84%E3%81%93%E3%81%AA%E3%81%97%E3%81%A6%E3%80%81%E4%BE%BF%E5%88%A9%E3%81%AB%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%81%97/
ESlint [Airbnbルール] + Prettierを適用／Next.js+TypeScript

## 概要
next.js + typescriptに、eslintをairbnbのルールで導入+ Prettierを連携させたので忘備録
参考：https://www.npmjs.com/package/eslint-config-airbnb-typescript?activeTab=readme
## 前提
#### そもそもなぜ、Airbnb???
開発者がより安全でバグの少ないコードを書くために、
Airbnbが長年の開発経験をもとに、JavaScript/TypeScriptにおけるベストプラクティスとしてまとめており、GitHubでも高評価を得ている。
また、ReactやTypeScriptを使うプロジェクトでも推奨される設定を提供しているため。
- TypeScript導入済
- Visual Studio Codeを使用
## 1. ESlint:Airbnbパッケージのインストール
```bash
npm install eslint-config-airbnb-typescript \
            @typescript-eslint/eslint-plugin@^7.18.0 \
            @typescript-eslint/parser@^7.18.0 \
            --save-dev
```
## 2. Prettierパッケージのインストール
```bash
npm install --save-dev eslint-plugin-prettier eslint-config-prettier prettier
```
## 3. `.eslintrc.json`の設定
Prettierの設定がESLintに統合され、コード整形と静的解析が統一されるようにします。
```.eslintrc.json
{
  "extends": [
    "airbnb",
    "plugin:@typescript-eslint/recommended",
    "airbnb-typescript",
    "next/core-web-vitals",
    "next/typescript",
    "plugin:prettier/recommended"
  ],
  "parserOptions": {
    "project": "./tsconfig.json"
  },
  "rules": {
    "prettier/prettier": [
      "error",
      {
        "singleQuote": true,   // シングルクオートを使用
        "trailingComma": "all", // 末尾のカンマを常に追加
        "semi": true,          // 文の末尾にセミコロンを追加
        "tabWidth": 2,         // タブ幅を2に設定
        "useTabs": false       // スペースを使用
      }
    ],
  },
  "ignorePatterns": ["prettier.config.js"] 
}

```
ちなみに`package.json`の該当部分はこんな感じです
```package.json
  "devDependencies": {
    "@eslint/js": "^9.12.0",
    "@types/node": "^20",
    "@types/react": "^18",
    "@types/react-dom": "^18",
    "@typescript-eslint/eslint-plugin": "^7.18.0",
    "@typescript-eslint/parser": "^7.18.0",
    "eslint": "^8.56.0",
    "eslint-config-airbnb": "latest",
    "eslint-config-airbnb-typescript": "latest",
    "eslint-config-next": "14.2.14",
    "eslint-config-prettier": "^9.1.0",
    "eslint-plugin-prettier": "^5.2.1",
    "prettier": "^3.3.3",
    "typescript": "^5.5.4",
    "typescript-eslint": "^8.8.1"
  }
}
```
## 3. ESlintの実行
このコマンドにより、ESLint はコードを解析し、可能な限り自動的に問題を修正してくれます。
また、Prettier のルールに違反していた箇所が自動的に修正され、手動でコードを修正する必要がなくなります。
```bash
npx eslint . --fix
```
## 4. 自動修正の設定
手動で`npx eslint . --fix`を実行するのは手間がかかるため、VSCode保存時に自動で修正する設定を行います。
#### 4-1.拡張機能のインストール
VSCodeにESLintとPrettierの拡張機能をインストールします。
#### 4-2.`settings.json`ファイルの作成
プロジェクトディレクトリの直下に`.vscode`フォルダを作成し、その中に設定ファイル`settings.json`を作成
```settings.json
{
  "editor.formatOnSave": true,        
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  }
}
```
以上の設定で、VSCodeでファイルを保存するたびに、ESLintによる自動修正と Prettierによるフォーマットが適用されます。
## 備考
バージョン外であるとの警告が出たため、バージョンを落としました
```bash
# typescriptのバージョンの確認
npm view typescript versions
# 安定版のTypeScriptの最新バージョン5.5.4を適用
npm install typescript@5.5.4 --save-dev --legacy-peer-deps
```
郵便番号辞書について

日本郵便株式会社から提供されている郵便番号データそのままDB化しても使い勝手が悪く、ひと手間加えることが必要です。すでにいくつかのベンダーが改変したデータを提供していますが、改めて何をすべきかを記載させていただきます。
なお、改変したデータもしくは改変したデータによるAPIを提供については
https://qiita.com/megane_/items/c8e4062697eaa785a103
で紹介されています。

## 郵便番号データを利用する目的
郵便番号データは郵便番号によって、住所の都道府県、市区町村、町域名を取得する、もしくは逆に都道府県、市区町村、町域名から郵便番号を取得するために利用します。このため、町域名が実際の町域名と一致することが重要なポイントとなります。
ところが日本郵便から提供されている郵便番号データは町域名をデータを柔軟に表現するための表現するためのカラムとして利用しており、そのままデータベース化しても正確な町域名が得られない場合が多く存在します。

## 何を改変する必要があるのか？
一番大きな問題は１つのデータが複数行で記述される場合があることでしたが、これについては2023年6月より1レコード1行のデータが提供されることとなり、問題はなくなりました。
それ以外で実施すべきことを以下に記述します。
* 町域名が「以下に掲載がない場合」「次のビルを除く」「XXの次に番地がくる場合」「〇〇一円」などと記述されており、実際の町域名ではないレコード
* 町域名に複数の選択肢が「、」区切りで提示されている場合
* 町域名に（）で複数の選択肢が提示されている場合（「、」と併用もある）
* 町域名が町域名、建物名、階数で構成されている場合
* 〇〇地割、第〇〇地割が町域に含まれる場合

また１つの郵便番号が複数の町域に割り当てられている場合、データをどのようにすべきかも考慮する必要があります。

## 郵便番号データの誤り？
以下の３つのデータは正しくないと思います。

|郵便番号|郵便番号データ|あるべきデータ|
|:-----:|:-----------:|:-----------:|
|4400833|飯村町西山、高山|飯村町（西山、高山）|
|4400032|岩田町居村、北郷中|岩田町（居村、北郷中）|
|4400041|岩田町宮下、道合|岩田町（宮下、道合）|

2024/11/27 追記）
日本郵便株式会社から連絡があり、2024/12配信分で修正いただけるとのことです。

## データの改変処理
上記のような処理を行うpython scriptを作ってみました。日本郵便株式会社から提供されているUTF-8型式のcsvファイルを入力すると、sqlite3のDBに結果を出力します。ただ、sqlite3でのサロゲートペア文字の扱いがわからなかったのでもそれについては文字化けしているかもしれません。
ご興味ある方がいらっしゃれば個別に提供させていただきます。

## 最後に
実際には事業所個別データにも対応しないと、住所入力でのアシストに使うには不十分です。これについては別途記事を書きたいと思います。
cookiestoreとは

# デフォルトのセッションストレージ
>RailsはデフォルトのセッションストレージとしてActionDispatch::Session::CookieStoreを用います。

https://railsguides.jp/security.html#cookiestore%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%AB%E5%AF%BE%E3%81%99%E3%82%8B%E3%83%AA%E3%83%97%E3%83%AC%E3%82%A4%E6%94%BB%E6%92%83:~:text=Rails%E3%81%AF%E3%83%87%E3%83%95%E3%82%A9%E3%83%AB%E3%83%88%E3%81%AE%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8%E3%81%A8%E3%81%97%E3%81%A6ActionDispatch%3A%3ASession%3A%3ACookieStore%E3%82%92%E7%94%A8%E3%81%84%E3%81%BE%E3%81%99%E3%80%82

デフォルトでcookieを使うのようになっているのか

# cookiestoreの特徴

### セッションハッシュ使ってcookieを使っている
>RailsのCookieStoreは`クライアント側のcookieにセッションハッシュを保存`します。サーバーはこの`セッションハッシュをcookieから取得することで、セッションIDを必要としなくなります`。こうすることで、アプリケーションのスピードは大幅に向上しますが、このストレージオプションについては賛否両論があるため、セキュリティ上の意味やストレージでの制約について以下の点を十分考えておかなければなりません。

### 容量
>cookieの`上限は4KB`です。cookieはセッションに関連するデータを保存する目的にのみお使いください。

目的外の物は保存しない

### Cookieが盗聴される可能性
>cookieは`クライアント側に保存`されます。クライアントでは、`失効したcookieにも内容が残っている`ことがあります。また、`クライアントのcookieが他のコンピュータにコピーされる可能性`もあります。`セキュリティ上重要なデータをcookieに保存することは避けてください`。
...
セッションcookieが自分自身を無効にすることはないので、`悪用目的で使い回される可能性`もあります。保存済みのタイムスタンプを利用して古いセッションcookieをアプリケーションで失効させるとよいでしょう。
### 一時的な情報だけcookieを使う
>cookieは本質的に一時的な情報です。サーバーはcookieに期限を設定できますが、期限が切れる前にcookieやcookieの内容がクライアント側で削除される可能性があります。`恒常性の高いデータは、すべてサーバー側で永続化`してください。
### デフォルトで暗号化されてる
>Railsはcookieを`デフォルトで暗号化`します。クライアントは暗号を解読しないかぎりcookieの内容を読み取ることも編集することもできません。秘密情報を適切に扱っていれば、cookieのセキュリティは一般的に保たれていると考えてよいでしょう。
>
>CookieStoreは、`セッションデータの保管場所を暗号化して安全にするためにencrypted cookie jarを利用します`。これにより、cookieベースのセッションの内容の`一貫性と機密性を同時に保ちます`。暗号化鍵は、`signed cookieに用いられる検証鍵と同様に、secret_key_base設定値から導出`されます。

https://railsguides.jp/security.html#%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8:~:text=Rails%E3%81%AECookieStore%E3%81%AF,%E5%B0%8E%E5%87%BA%E3%81%95%E3%82%8C%E3%81%BE%E3%81%99%E3%80%82
個人的に思う、RDSを使う場合に便利で安全なDBパスワード管理方法とDB接続方法

## 結論
データベースのパスワードはSecrets ManagerかSSM パラメータストアで管理するとパスワード覚えたり、メモしたりする必要がなく安全に管理でき、mysqlクライアントを使った接続が簡単になります。

## 背景
パスワード管理には
* 人間が記憶して覚える
* 個人でメモをとる
* Redmineなどプロジェクト管理ソフトに記載をする
* パスワードリマインダーに覚えさせる

などなど、いくつかの手法がありますが、これらの方法は個人の管理依存している場合は引き継ぎが発生した場合に問題が起きやすかったり、AWS外に保存するのはセキュリティ上、推奨されません。

## AWS上でパスワード保存する方法

* Secrets Managerに保存する
* SSM パラメータストアに保存する

どちらにもメリット・デメリットがありますが、どちらでもパスワード管理することは可能です。

Secrets Managerの方が高機能で、パスワードだけでなくIDやエンドポイントもの情報も含めて管理しており、パスワードローテーション機能などもあります。
しかしSSM パラメータストアより利用料金が高く、機密情報を取得した際の処理が少し面倒です。

対して、SSM パラメータストアはシンプルです。keyと指定された文字列やリストを1対1で保存します。
指定日時でのパラメータの削除などはありますが、シークレット情報を保管するのに特化したサービスではないので、パスワードローテーション機能などはなくSecrets Managerと比較するとシンプルな分できることが少ないです。

## MySQLクライアントで便利に使う方法

※ここでは事前にSecrets Manager や SSM パラメータストアの設定は終わっているものとして扱います。

Secrets Manager の場合

```
mysql --host {RDSのエンドポイント} -u {ユーザ名} -p${aws secretsmanager get-secret-value --secret-id {Secrets Managerの名前} --query 'SecretString' --output text | jq ".password" -r}
```

SSM パラメータストアの場合

``` 
mysql --host {RDSのエンドポイント} -u {ユーザ名} -p${aws ssm get-parameter --name {パラメータストアのキー} --with-decryption --query 'Parameter.Value' --output text}
```

このようにパスワードをAWSサービス上から取得してくるようにしておくと、ドキュメントに RDS へのアクセス方法などをまとめる時もパスワードをドキュメントに直書きせず済み、ドキュメントを読んでいる方からしてもコピペでアクセスできるので、手軽にアクセスできます。
カスタムホスト名に" _ "(アンダースコア)を使わないようにしている理由

# 先に結論

PHPで**filter_var**を使ってURLサニタイズをすると、**アンダースコアは不正URLとして弾かれてしまう**ため。  

代わりに**ピリオド**などを使うのが正しい。  

## 経緯

WordPressを使って、リダイレクト機能の実装を行っていました。  
サニタイズについて知らなかった頃、慣習としてディレクトリ名と同じカスタムホスト名を付けて、ローカル環境で使用していました。  

```
http://example_project
```

この環境下であることを前提に、以下のような関数を実行します。  

``` redirect.php
function custom_redirect_sanitize_url($rules) {
    $sanitized_rules = [];
    $rules = json_decode($rules, true);
    
    foreach ($rules as $key => $value) {     
        if (filter_var($key, FILTER_VALIDATE_URL) === false || filter_var($value, FILTER_VALIDATE_URL) === false) {
            add_settings_error(
                'simple_redirect_rules',
                'invalid-url',
                '無効なURLです。正しいURLを入力してください。',
                'error'
            );
            return false;
        }

        $sanitized_rules[$key] = $value;
    }

    return $sanitized_rules;
}
```

なお、`$rules`の構造は以下のようになっています。

```
a:1:{s:31:"http://example_project/";s:38:"http://example_project/home";}
```

つまり、
`"http://example_project/"`にアクセスされたら、
`"http://example_project/home"`に飛ばすよ、
というだけの機能です。  

しかし、何度やってもうまく行かずWordPressが不慣れだったのもあって、原因の特定に時間がかかってしまいました。  

## 解決策

``` diff
- "http://example_project/"
+ "http://example.project/"
```
に直した。それだけ。

デバッグ関数を使いながら原因を辿って行ったところ、
`filter_var($key, FILTER_VALIDATE_URL)`
において"_"(アンダースコア)が原因でURLとして認識されず、wp_optionsにリダイレクトルールが適用されていなかったのでした。

余談ですが、カスタムホスト名を修正するために変更した箇所は以下の通りです。  

- apacheのhttpd-vhosts.conf
- driversのhosts
- wp-optionsのsiteurlとhome

これで無事、実装したかった機能を追加することができました！
Latexのstyleファイルでmaketitleをカスタマイズ（再定義）したい

# maketitleって何ィ
latexにおいて，titleを出力するコマンドのことです．`\title{}`や`\author{}`などを使用して，属性を指定できます．

例えば，

```latex
\documentclass{article}

% タイトル、著者、日付を設定
\title{俺のちょうすげー論文}
\author{新田真剣佑}
\date{\today}

\begin{document}

% タイトルを出力
\maketitle

\end{document}
```

とすれば，
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457534/824f74c6-8aa0-6977-a1ab-1d36bb4e9fc7.png)
みたいに出力されます．

# maketitleの出力フォーマットを変えたい

## maketitleはどこで定義されている？
`\makeltitle`で出力される内容は，**クラスファイル**の中で定義されています．クラスファイルってのは，

```latex
\documentclass{[ここで指定するやつ]}
```
です．ただ今回は，クラスファイルはそのままで，**スタイルファイル**を変更して`\maketitle`をカスタマイズします．スタイルファイルは拡張子`.sty`で`\usepackeage{}`を使って読み込みます．

## スタイルファイル内での再定義
コマンドの再定義には`\renewcommand{[再定義するコマンド]}{[変更後の内容]}`を使います．`\maketitle`を再定義したいので，
```latex
\renewcommand{\maketitle}{
  [出力内容]
}
```
みたいにすればよいです．

## 属性の表示
### デフォルトで定義されている場合
デフォルトで定義されている属性（`\title{}`とか`\author{}`）を`\renewcommand`内で呼び出すには，`\@[属性名]`を用います．ただし，Latexの識別子には，アットマーク@を使用できないため，`\makeatletter`と`\makeatother`で囲む必要があります．

### 例

```latex
\makeatletter
\renewcommand{\maketitle}{
  \begin{center}
    {\huge\bfseries\@title}
    \vspace{1cm}
    {\Large\@author}
    \vspace{0.5cm}
    {\@date}
    \vspace{1cm}
    \hrule
  \end{center}
}
\makeatother
```

### 出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457534/ca0c5afc-37ec-d96f-16f2-ef78320890f0.png)

こんな感じ

### 新しく属性を作成する場合
`\newcommand`を使って以下のように定義します．

```latex
\makeatletter
\newcommand{\[作成する属性名]}{\gdef\@[作成する属性名]}
\[作成する属性名]{[デフォルト値]}
\makeatother
```
その上で，上記のように呼び出してください．

### 例
```latex
\makeatletter
\newcommand{\hobby}{\gdef\@hobby}
\hobby{}
\makeatother

\makeatletter
\renewcommand{\maketitle}{
  \begin{center}
    {\huge\bfseries\@title} \\  % タイトルを大きく、太字にする
    \vspace{1cm}
    {\Large\@author} \\          % 著者を少し大きくする
    \vspace{0.5cm}
    {\@date} \\                  % 日付をそのまま表示
    {趣味：\@hobby}
    \vspace{1cm}
    \hrule                       % タイトルの下に横線を引く
  \end{center}
}
\makeatother
```

### 出力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457534/7760d153-46cf-25b2-aaca-c3be841cf955.png)

はぁい

# さいごに

真剣佑になりたい．
OracleからPostgresqlに移行する際にNULLと空文字の違いで起こった問題と解決策

# はじめに
OracleからPostgreSQLに移行した際、NULLと空文字の扱いの差で起こった問題を記録として残そうと思います。

この記事では **Oracle側に合わせることを方針（空文字をNULLに変換する）** として、起こった問題と解決策を書いていこうと思います。

# NULL・空文字問題とは
Oracleでは`''(空文字)`と`NULL`はNULLとして扱いますが、
PostgreSQLでは`NULL`のみNULLとして扱い、`''(空文字)`は空文字として扱います。
この違いのせいで移行した際、どちらに合わせるか方針を決めてSQL文を書き直すなどの必要があります。


# 問題1. 空文字が含まれるCASTによるinvalid input syntaxエラー
## 事例1

``` sql:エラーとなったコード
-- 変数Aには空文字('')が入っている
CAST(変数A AS FLOAT)
```
``` :エラー文
invalid input syntax for type double precision: ""
```
「FLOAT型(type double)に対する無効な入力やで」という意味

## 対策1
**nullif関数** を使用して対策を行います。
nullif関数は第一引数と第二引数が等しい文字列であればNULLを返してくれます。

CASTしたい値が変数Aだとします。以下のようにすることで変数Aに空文字が入ればNULLが返り、そうでなければ変数Aの文字列がそのまま通ります。
``` sql
CAST(nullif(変数A,'') AS FLOAT)
```

# 問題2. COALESCE関数通り抜け問題
## 事例2
COALESCE関数（OracleではNVL関数）は`NULL`をデフォルト値に置き換えるためによく使用されます。

例えば、以下のように変数Bに`NULL`が来たら0に置き換える動作があったとします。変数Bの値が正しく`NULL`ならば問題ないのですが、空文字だった場合はデフォルト値に置き換えることなくそのまま空文字を素通りさせてしまいます。
``` sql:変数に空文字が入ると置き換えてくれない
COALESCE(変数B,'0')
```

## 対策2
はい。またもや登場nullif関数くんです。
``` sql
COALESCE(nullif(変数B,''),'0')
```

先ほども解説しましたが、`nullif(変数B,'')`で空文字をNULLに変換することで正しく置き換えが機能するようにしています。

# 問題3. 空文字を日付型に変換すると…
## 事例3
以下のようなSQLがあったとします。
``` sql
TO_DATE(RPAD(変数C,12,'0'),'YYMMDDHH24MISS')
```
変数Cにちゃんと`NULL`や数字の文字列が入れば問題ないのですが、空文字がはいると本来ならば`NULL`にしたいところ`2000/01/01`という値になってしまいます。
これは空文字をRPAD関数で0埋めした結果`000000000000`となるためですね。

ちなみにRPAD関数関係なく
``` sql
TO_TIMESTAMP('','YYMMDDHH24MISS')
```
であった場合も`NULL`にはなりません。

## 対策3
3度目の登場、nullif関数です。説明は省きますが以下のようにすればOKです。
``` sql
TO_DATE(RPAD(nullif(変数C,’’),12,'0'),'YYMMDDHH24MISS')
```
空文字を`NULL`にしてくれるので上手く行きます！

# 最後に
今回は全てnullifの力で乗り切りましたが、これが最適解ではないかもしれません。なんかいい感じの楽な方法があればいいんですけどねー。

nullifについては以下をみて。

https://www.postgresql.jp/document/16/html/functions-conditional.html#FUNCTIONS-NULLIF
Macのキーボードを快適に使うやつ

長押しして文字を入力
```
defaults write -g ApplePressAndHoldEnabled -bool false
```

キーリピーテーション
```
defaults write -g InitialKeyRepeat -int 12 # normal minimum is 15 (225 ms)
defaults write -g KeyRepeat -int 1 # normal minimum is 2 (30 ms)
```
supabaseのテーブルにデータを挿入できない

supabaseでデータの挿入を行う際にエラーが発生して、更新した値が返されませんでした。

## 問題のコード
```route.ts
const { data, error } = await supabaseClient
          .from("テーブル名")
          .insert([データ])
```

## エラーメッセージ
```
Error inserting data into Supabase: undefined
```

## 解決方法
```route.ts
const { data, error } = await supabaseClient
          .from("テーブル名")
          .insert([データ])
          .select();  //これが必要
```

## 原因
insert後値を返すには.select()が必要でした。
v2 以降の新機能らしいのでそれ以前の記事などを参考にする際は気をつけて下さい

### 参考文献

https://supabase.com/docs/reference/javascript/upsert

https://www.reddit.com/r/Supabase/comments/x20aqc/insert_works_but_does_not_return_data_or_error/
【AWS】AWSコンソールを使用した構築手順１－２

## 休憩終わり（前回の続き）
前回の記事については　→[AWSコンソールを使用した構築手順１－１](https://qiita.com/Hiro_tech/items/7b63e3f7899e75d9845f)を参照してください。

項番は、分かりづらくなるなと思ったので、続きの９から書いていきます。
それでは、早速やっていきます。

### ９．メインルートテーブルの編集
#### ９－１．前回の構築手順①で作成したパブリックサブネットを選択
#### ９－２．このサブネットにアタッチしているルートテーブルを選択
#### ９－３．ルートテーブルの「ルートを編集」押下
#### ９－４．「ルートを追加」を押下し、下記２つのルートを追加する。
    　・「10.0.0.0/24（パブリックサブネットのIPv4 CIDRブロック）」、「NATゲートウェイ（前回の構築手順➀で作成したNATゲートウェイ）」の選択
     ・「0.0.0.0/0」、「インターネットゲートウェイ（前回の構築手順➀で作成したインターネットゲートウェイ）」の選択
#### ９－５．「変更を保存」押下

### １０．EC2インスタンスへログインし、ローカルPCへのSSH接続確認
#### １０－１．構築手順①で作成したEC2を選択
#### １０－２．画面右上の「接続」押下
#### １０－３．「SSHクライアント」を選択し、CloudShellを開く。
#### １０－４．CloudShell右上の「アクション」　→　「ファイルのアップロード」選択
#### １０－５．EC2作成時に作成したキーペアファイルを選択し、「開く」押下
#### １０－６．Cloudshell内で、以下の操作を実施
     ・chmod 400 “キーペアファイル名“
     ・ssh -i “キーペアファイル名” ec2-user@（EC2のパブリックIP）
#### １０－７．EC2インスタンスからqiitaのHP（qiita.com）に疎通確認する。
     ping qiita.com
:::note warn
注意
私のPCの環境はWindowsであり、事前にキーペアをWinSCPを使用し、EC2上にアップロード済でした。上記の作業ができない場合は同じ方法をお試しください。
:::

### １１．作業完了('Д')

## 構築してみての感想
 　構築手順通りに作業を進めていくと、上記の項目の中でも細かい設定の部分でつまづくことがけっこうありました。
 （ルートテーブルの設定、SSH接続時のキーペアをAWS上へのアップロードなど）
 
 なので、私自身、書籍や解説動画を見て、頭の中で理解するだけだと、不十分だと感じたので、実際にＡＷＳコンソールを使用し、手を動かすことをお勧めします。
 
 最後に、今回の手順で、間違えている箇所やここもう少し詳しく教えてほしいといったリクエストをコメントでお待ちしております。
 是非、ＡＷＳについて学んでいきたいという方の参考になれば幸いです。
[tips][cpp][problemSolver] 初期化

# 配列の初期化

さっさと初期化したい時に。

## マス目系

h * wのマスに文字が入る二次元配列
```cpp
int h = 100;
int w = 500;
vector<vector<char>> c(h, vector<char>(w))
```

```cpp
int h = 100;
int w = 500;
vector<string> c(h)
```

## DP系

DPとかでのテーブル定義を二次元配列
※memsetは`cstring`をヘッダに指定し、-1か0をセットするときのみに使うのがベター。
```cpp
#include <cstring>
long long dp[100000][110] = {0};
memset(dp, -1, sizeof(dp));
```

何も指定しなければ0が入る。これがシンプル
```cpp
int x[5] = {}; // {0, 0, 0, 0, 0}
```

### INFINITYを初期値として与える場合

```cpp
const int INF = 1000000007;
```

or
```cpp
const int INF = 1<<29;        // 十分大きい値にする, INT_MAX にしないのはオーバーフロー対策
```

long longなら
```cpp
const long long INF = 1<<60;
```

`int`は32bit、`long long`は64bitなので値制約が10^9とかなら`long long`使用する。

## 参考
https://rinatz.github.io/cpp-book/ch03-01-arrays/
https://qiita.com/Nichi10p/items/cabdb3d5ad3b81446748#memset-%E3%81%8C%E6%9C%89%E5%8A%B9%E3%81%AA%E5%A0%B4%E5%90%88
SQLの小技・WITH句のすすめ


# SQLの読みにくさの原因
- 深いネスト：集約や件数減らしでfromのネストは容易に増えていく
  特にfromのネストはSQLの冗長な記述法も相まって非常に見辛くなる
- SQLのフォーマットに標準がないのも問題に思う

----
# どうする？　→そこでwith句
- select文に別名を付けられる
- そのSQL文の中でのみ有効なviewとみなせる
- あるviewを、別のviewから参照できるのでfrom多段を減らせる

----
# with句の意義（1/2）
- ネストの解消
それだけ・・・？と思われるかもしれませんが、ネストはコードを読みにくくする大きな要因の１つです。


----
# with句の意義（2/2）
- 問題の分離：新たな集合を作る・それらを組み合わせる・値を加工する、これらを書く場所が明確になる
- 複雑なUPDATEで威力を発揮することがあるようです

----
# 注意点
- エディタを行ったり来たりしないといけなくなるかも
- 未検証だが実行計画に影響が出るかも

----
# DBのTips
- テーブル名やカラム名は小文字の方がいい
  書きやすく、読みやすい。良いことしかない
- USING：JOINキーが同じ名前のときにシンプルに書ける
- 日付型／時刻型をうまく使う
- クラウド時代なのでタイムゾーンに気を配る

----
# 最後に
- SQLは昔から使っているからこそ、知識がなかなかUPDATEされない気がします
- 実務でゼロから設計する機会は少ないですが、SQLはそうでもないはず！
機械学習モデルから毎回違うサンプルが取り出されてしまうときの対処法

# きっかけ
卒業研究の一環で読唇（lip reading）の推論済みモデルをgithubからクローンして動かしていました。ミニバッチ学習時は問題なかったのですが、個別に推論をしたところ、毎回違う出力結果が出てしまっておりました。

# 考えるべきこと

## 1. Dataloaderの構造
以下のように**shuffle=True**になっていると、Dataloaderはデータセット全体からbatch_sizeだけサンプルをランダムに取ってきます。そうすると1つのデータを推論したいとき、毎回違うサンプルで行われてしまいます。

```python
dset_loaders = {x: torch.utils.data.DataLoader(
                        dsets[x],
                        batch_size=args.batch_size,
                        shuffle=True,
                        collate_fn=pad_packed_collate,
                        pin_memory=True,
                        num_workers=args.workers,
                        worker_init_fn=np.random.seed(1)) for x in partitions}
```

## 2. random_seedの有無
以下のように**random_seed**の記載が無いと、推論結果が毎回異なってしまいます。

```python
torch.manual_seed(1)
np.random.seed(1)
random.seed(1)
torch.backends.cudnn.benchmark = True
```

## 3. glob.globの使用
**os.path.join**メソッドを使用する際、**glob**を用いると、データがランダムな順序で渡されます。以下のようにsort()メソッドを使用することで解決されます。

```python
        search_str_mp4 = os.path.join(dir_fp, '*', self._data_partition, '*.mp4')
        self._data_files.extend( glob.glob( search_str_mp4 ) )
        
        #glob.glob()によるファイル検索の際に、OSによってファイルがランダムな順序で返される
        self._data_files.sort()
```
JITと積載最適化ソフトウェア

スマートテクノロジーの進展に伴い、サプライチェーンのスマート化も避けられないトレンドとなっています。サプライチェーンの重要な一環である積載輸送は、そのプロセスや結果の最適化が企業にとってコスト削減と効率向上を目指す重要な戦場となっています。

さまざまな不安全要因によって海運環境が不安定化し、続いて海運費が急騰する中、企業はコンテナスペースを最大限に活用し、空気を運ばず、全体の物流プロセスをリーン管理する方法を模索しています。

現在、ますます多くの企業が「JIT生産」モデルを実現しようとしています。これは「ジャストインタイム生産」を意味し、在庫水準を減少させ、生産効率を高めることを目的としています。 JITとは何か？ なぜ企業はこのモデルを実現しようとするのか？ このモデルの利点は何か？ このモデルを実現するためにはどのような課題があるのか？一緒に探求していきましょう。

JITの核心概念：

需要に応じた生産：顧客が必要なときにのみ製品を生産または納品し、事前に生産したり大量に在庫を抱えたりしない。
在庫の最小化：原材料、中間製品、製品の在庫を減らすことで、倉庫コストと資源の無駄を削減する。
継続的な改善：リーン生産とプロセスの最適化を通じて、無駄を減らし、品質と効率を向上させる。
サプライチェーンの協調：供給業者が生産のリズムに合わせて原材料や部品を時間通りに供給できることを要求する。
JITの利点：

在庫コストの削減：在庫に占有される資金と保管コストを減少させる。
無駄の削減：正確な生産によって、過剰生産や材料の無駄を減らす。
効率の向上：プロセスを最適化し、停止時間を減少させることで、生産効率を高める。
品質の向上：問題をタイムリーに発見し、不良品の発生を減らす。
JITの課題：

サプライチェーンへの依存：供給業者が時間通りに納品できないと、生産に影響が出る。
柔軟性の要求：生産ラインは需要の変化に迅速に対応できるように調整する必要がある。
リスク管理：在庫レベルが低いため、サプライチェーンの中断が生産に大きな影響を及ぼす。
JITは、最初に日本のトヨタ自動車で成功裏に導入され、その後他の製造業界に広く普及しました。これはリーン生産システムの重要な要素であり、企業がより効率的かつ柔軟な生産管理を実現するのに役立ちます。しかし、JITモデルの最大の課題は、供給業者が時間通りに納品することであり、どのようにより良く迅速に実現するかです。

3D積載最適化ソフトウェアはこの課題に効果的に対処でき、ますます多くの企業がサプライチェーンプロセス管理に応用しています。例えば、LoadMaster積載最適化ソフトウェアは、マイクロ秒単位の速度で正確な最適積載プランを計算し、貨物のサイズが正確で、合理的なパラメータやルールが設定されている限り、実行可能なプランを保証します。従来の手動で数日かかって粗いプランを算出する手間と比較して、人工コスト、時間コスト、機会コストを大幅に削減しつつ、効果が顕著に向上し、企業の市場競争力を高めるための追加のアドバンテージを得ています。

四川一汽豊田は2013年に積載マスターソフトウェアを購入し、成都および天津の物流センターでアフターサービス部品の物流積載問題を解決するために使用を開始しました。現在まで11年以上の協力を続けています。彼らの日常的な注文は以下の2種類に分けられます：①安定した注文；②臨時追加貨物の注文。この2種類の注文に対する物流センターの業務プロセスは以下の通りです：①安定した注文に基づいて出荷計画を策定する。出荷計画が確定した後、手作業で貨物の体積などを大まかに推定して積載プランを導き出し、必要な輸送車両の型式および数量を見積もった後、詳細な二次包装と積載の詳細なプラン図を作成します。②臨時追加貨物の注文が発生した場合、手動で積載プランを再評価し、再度輸送に必要な車両の型式と数量を見積もり、最後に新しい積載図を再作成します。

しかし、このような処理プロセスでは、顕著な問題が発生し、頭を悩ませることが多いです： ①推定貨物量に基づく積載図と実際の集荷積載時に差異がある； ②緊急追加注文の場合、積載プランを即座に柔軟に調整できない； ③手動での作成は時間がかかり、労力がかかり、エラー率が高く、工数が膨大。

積載マスターを使用した最適化後 このような状況の中で、彼らは積載マスターソフトウェアに出会い、現在のビジネス課題の解決に役立つことを期待しました。実際のデータを使ってテストを行い、積載マスターの強力な機能を十分に理解した結果、以下のことがわかりました： ①積載マスターソフトウェアは大量の貨物データを迅速にインポートし、正確な積載プランを迅速に提供でき、積載ニーズを満たすだけでなく、集荷車両の積載率を向上させることもできる； ②注文数量に臨時の調整があった場合、既に出された積載プランを柔軟に調整し、新しい積載プランを迅速に計算できる； ③ソフトウェアは3Dの積載プランを提供するだけでなく、詳細な積載手順も提供し、現場の作業員が現地での積載を指導するのに便利； ④全体のプロセスが迅速かつ効率的で、算出、積載、輸送のサイクルが大幅に短縮された。

今後、コスト削減と効率向上は「細部から効果を求める」ことによりますます具体化され、JITモデルは製造企業が実現しようとするモデルとしてますます一般化するでしょう。3D積載最適化ソフトウェアは、間違いなくこの目標を実現するための強力な助手となるでしょう！
プログラム未経験でSchooのエンジニアになった話

初めまして！
Schooの新卒エンジニアのたま(@himari_karesaki)です！
今日は自分がSchooのエンジニアとして働こうと思った理由を振り返ってみたいと思います。

# 前提
私は学生時代、社会学部で「シングルマザーの貧困がなぜ無くならないのか」というテーマで卒論を書くほど、全然プログラミング関係ないじゃんみたいな勉強をしていました。
プログラミングに触ったことといえば、空いた時間にHTMLとCSSの本をやったことがあるぐらいです。

そんな私がなぜweb開発者としてキャリアをスタートしようと思ったのか、なぜSchooだったのかについて書こうと思います。

# もっとクリエイティブなことをしなよ
私が大学3年生の時に企業のインターンシップに色々参加していた時にゼミの先生に言われた言葉です。
当時私がインターンに行っていたのは大手の保険会社や金融機関の営業職でした。なぜかと言われると、そこまで多くの理由はないですが、やっぱり「大手」がかっこいいかなとか、「お金」を扱う仕事ってやり甲斐があるだろうなと感じていたからです。
でも、なんだか自分としてもあまり「大手」や「金融」の企業やそのインターンで出会った同期たちとの雰囲気が合ってないんじゃないかなという不安を感じていました。

そんな中、ゼミのフィールドワークにいったおでん屋さんでゼミの先生にこういう企業のインターン行ってるんだよね、という話をしたら、「全然合ってない気がする。たまちゃんはもっとクリエイティブな方が良いんじゃない？」と言われました。「クリエイティブ」。自分の中ではそれまで認識できていなかったけれど、確かに存在した価値観が表面化した瞬間だったなと思います。

# クリエイティブって何？
クリエイティブとは一体どういうことなのだろう。
アルバイトでIllustratorやPhotoshop、PremiereProなどを使って広報物を作成していましたが、それがクリエイティブなのか？
HTMLとCSSでサイトを作成したことがあったが、それはクリエイティブだったのか？

自己分析に自己分析を重ねました。
大量のA4用紙を埋め尽くすぐらいには自己分析をしていました。
その中で、自分の価値観として、「誰もが平等に生きられる社会を作る」「ものを作りたい」というキーワードが見えてきました。

# 「世の中から卒業をなくす」
この言葉にビビッときました。
「誰もが平等に生きられる社会を作る」というキーワードで会社を探していたものの、営利組織であるが故に実際には社会作りにあまり意識が向いていない印象の会社も多く、決め手に欠く状態が続いていました。
自分たちの営利は追求しつつ、誰もが平等に生きられる社会を作ることに繋がりそうだ。そう思ってSchooの面接を受けることにしました。

[余談]
私は最初、エンジニアとして採用フローを受けていませんでした。
他に選考を受けていた会社は全てエンジニアとしての採用を受けていたのですが、エントリーしてしまったのが総合職で、エンジニア採用があるということを知らずに採用フローを受けていました。
ただ、どうしてももう一つの価値観である「ものを作る」というところが引っ掛かっていました。当時、Schooの採用フローの中で、最終面接の前に社員面談という、今悩んでいる箇所や自分のキャリアについて相談できる時間がありました。その中で、社員の方に相談し、そこで採用フローが増えるけれど、それでも良ければ「エンジニア採用」も受けてみたら良いのではないか？というご回答をいただき、二つ返事で「受けたいです！」と答えました。

そこからはエンジニアの適性を図ると噂のweb適正テストを受け、開発部門の採用を担当されている方との面接を経て、最終面接に進むことができました。
最終面接では、総合職とエンジニア職、やりたいのはどっち？ということを聞いていただいて、総合職で面接に関わってくれた方々に時間を使っていただいたのは申し訳ないけれど、エンジニアになりたいですと話し、エンジニアとして採用される、という奇跡が起きました。

# 入ってから学ぶ
webの自社開発系のエンジニアといえば、STEM教育を施されてきたアスリートのみがなれるという印象を持っている方も多いと思います。
確かにその方が会社にとっても本人にとっても良い時もあるかもしれません。
ですが、当時の私の価値観や考え、伸び代を考慮し、採用してくださった会社には感謝しかありません。
そのおかげで、やりたかったことをやれるキャリアをスタートすることができましたし、楽しく仕事ができています。
また、開発部門のマネージャーにも、「Schooは入ってから学べる環境」という言葉を言ってくださいました。
「世の中から卒業をなくす」というSchooのミッションの通り、Schooは社会人として働きながらも、学び続ける人が多くいます。
学びを信じる企業だからこそ、未経験者でも学べば十分活躍できる人材になる、と信じてくれたのだと思っています。
これからも、現状に満足せず、楽しく学び続けていきたいと思います。


---
schooでは一緒に働く仲間を募集しています！
↓↓↓↓↓↓↓

https://corp.schoo.jp/careers/graduates

https://corp.schoo.jp/careers
Visualforce Page ボタンクリック後、下のほうに結果を表示する書き方

## 検索ボタンクリック後、下の方に結果を表示する

[apex:iframe](https://developer.salesforce.com/docs/atlas.ja-jp.pages.meta/pages/pages_compref_iframe.htm)

>Visualforce ページ内のインラインフレームを作成するコンポーネントです。

page1:

```html
<apex:page controller="MyVFController">
<apex:form id="form" target="_self">
<apex:commandButton value="Search" action="{!search}"/>
</apex:form>
<apex:iframe id="searchPage" src="{!moveToUrl}" ></apex:iframe>
</apex:page>
```
Apex1:
```apex
public class MyVFController {
    public String moveToUrl {get; set;}   

    public MyVFController() {
    }

    public void search() {
        this.moveToUrl = '/apex/MyVFpage2?id=' + 'ID12345' + '&othparam=' + 'ABCDE';
    }
}
```

page2:
```html
<apex:page sidebar="false"
    tabStyle="User"
    controller="MyVFController2"
    action="{!doInit}"
    >

    <apex:pageBlock >
    <apex:pageBlockSection title="取引先の総件数　：　{!total}  件">

    </apex:pageBlockSection>
    </apex:pageBlock>
 </apex:page>
 ```

Apex2:
```apex
public class MyVFController2 {

    public MyVFController2() {
        String rId = ApexPages.currentPage().getParameters().get('id');
        system.debug('*** rId=' + rId);
    }
    public void doInit() {
        system.debug('*** doInit');
    }
    public Integer getTotal() {
        return 100;
    }
}
```

Searchボタンをクリックすると、ボタンに下方に結果が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/bd8f35fe-5feb-b1c8-b626-200461c469cc.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3894299/3b2305ef-d185-4c96-acbf-d3fbad62596b.png)
Windows PCでgit pushを行うまで

# この記事について
Windows PCから自分のGithubのレポジトリに変更を加えたく、環境を整備していました。途中でつまづきポイントがあったので、備忘録がてら整理しようと思います。

# 環境
OS: Windows 11

# Windowsにgitを導入する。
Windowsにgitが入っていない人は下記のページを参考にして導入してください。
https://prog-8.com/docs/git-env-win

# 1. sshキーの生成
まずはsshキーを生成します。
```sh:shell
$ ssh-keygen -t ed25519 -C "your e-mail address"
```
Overwriteするかどうか聞かれます。`y`にしないと進めないので一旦`y`にしました。将来何かトラブルが起きるかもしれませんがそれはそのときで。
```sh:shell
 Generating public/private ed25519 key pair.
 Enter file in which to save the key (C:\Users\sophytoeat/.ssh/id_ed25519):     
 C:\Users\sophytoeat/.ssh/id_ed25519 already exists.
 Overwrite (y/n)? y
 ```
パスキーの設定を聞かれます。ここで何かパスキーを入力すると`git push` の度にパスキーを聞かれることになるので、セキュリティ上問題がなければパスキーを入力せずにエンターキーを押します。
```sh:shell
 Enter passphrase (empty for no passphrase):
 Enter same passphrase again:
 ```

# 2. 公開鍵の登録
### 公開鍵の表示とコピー
以下のコマンドで公開鍵が表示されるので、それを全てコピーする。
```sh:shell
$ cat C:\Users\username\.ssh\id_ed25519.pub 
```
# 3. sshキーの登録]
### 生成された公開鍵をクリップボードにコピー。
```sh:shell
$ pbcopy < ~/.ssh/id_ed25519.pub
```
### Githubにコピーした公開鍵を追加する
GitHubの「Settings（設定）」から「Deploy keys」を選択(Github pageのリポジトリでは「SSH and GPG keys」ではなく「Deploy keys」になっていた)し、「Add deploy key」をクリックします。
**※この時に「Allow write access」にチェックを入れるのを忘れないように**

# 4. ssh接続をテスト
```sh:shell
$ ssh -T git@github.com 
```
以下が表示されると成功。
```sh:shell
 Hi sophytoeat/sophytoeat.github.io! You've successfully authenticated, but GitHub does not provide shell access.
```

# 5. git pushまで
プッシュ先のリモートリポジトリを指定。URLはGitHubの作成したリポジトリ画面を開いて、 「HTTPS/SSH」と書かれたボタンの「SSH」を押してください。 `git@github.com`から始まる1行をコピーして`<URL>` の部分にペーストしてください。
```sh:shell
$ git remote add origin <URL>
```
以下のコマンドを入力するとpushが出来るはずです。
```sh:shell
$ git add .
$ git commit -m "test"
$ git push
```

# 参考文献
https://prog-8.com/docs/git-env-win
https://qiita.com/suke_qiita/items/0ce8b55d0b8af4258dc6
Redmine チケットをバックアップからリストアする

# Redmine チケットをバックアップから復活させる手順

## 経緯

:::note alert
休暇申請のチケットを整理（古いものを削除）中、誤って直近の 100 チケットを削除してしまった。
なんとか復活させたい…
:::

・私のチームでは休暇申請を Redmine のチケットで管理しています。


## 前提

:::note info
MySQL データベースのバックアップは毎日実施している
:::

:::note info
本番機がダウンしたときのためバックアップ機を用意してある
・本番と同じRedmine環境を構築済
(CrowdStrike障害時役に立ちました）
:::

## バックアップ機での作業

1. バックアップ機に前日(削除前)の DB バックアップをリストアする
1. プロジェクトのチケット一覧を表示させる
1. リストの下の「他の形式にエクスポート」から csv を選択する
1. すべての項目、にチェックしてエクスポートを実行する
1. エクスポートしたファイルをエディタで開いて必要な箇所以外を削除する
1. 最初の行がカラム名なのでそのままにする→インポート時、この情報が使われる
1. 編集したファイルを本番機にコピーする

## 本番機で作業

1. プロジェクトのリストを表示させる
1. 右上の ... を押す
1. インポートを選択する
1. インポートするファイルを選択する（必要な箇所を選択したもの）
1. 次へ →　次へ
1. 画面表示を確認、フィールドの対応関係があっていることを確認する
1. インポートを実行する
1. プログレスバー表示が 100% になればOK
1. チケットのリストを確認する

## ステータス・担当者がデフォルトになってしまうので修正

ステータスと担当者は csv が反映されず、デフォルトになってしまったので手作業で修正

1. チケットのリストで必要なものを選択する(リスト左のチェックボックスを個別にチェック)
1. 右クリック
1. ステータスを選択して、目的のものに変更する
1. 担当者を変える場合も同様にする
Exchangeメールの引き継ぎをOutlookから行う

退職や異動に伴い、取引先とのメールを後任に引き継ぐことがありますよね。
Microsoft Exchange のメールではそれが簡単にできるので、その手順を紹介します。

# 手順
画面表示は【**新しいOutlook**】または【**Outlook on the web (OWA)**】のものです。
【**古いOutlook**】では画面表示が異なります。

退職者（異動者）、後任者それぞれで実施します。

### 退職者（異動者）の操作
#### 引き継ぐフォルダを右クリックし「共有とアクセス許可」を選択
ここでは「受信トレイ」を引き継ぐことにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/69dde491-e931-3efd-999a-48d55f4928ed.png)

#### 「＋」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/abeb3861-f974-8797-462c-a53b1d2107bf.png)

#### 後任者のメールアドレスを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/90d0af5d-96db-10e8-39bc-b4d30aed50a5.png)

#### アクセス許可を設定
アクセス許可レベルには「編集者」を指定します。
アクセス許可レベルを変更すると、チェックが自動で入ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/53b12d99-a1db-d6e4-71e3-47ffbe8ac446.png)

### 後任者の操作

#### 「･･･」を右クリックし「共有フォルダまたはメールボックスの追加」を選択
「･･･」はアカウント名（モザイク箇所）の右にあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/d63abecc-b237-9aa2-4159-ab639de32b19.png)

#### 退職者（異動者）のメールアドレスを入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/7eeebac5-a97c-ddd6-3d73-a2d2270ab64a.png)

#### 共有アイテムを確認
共有元アカウント名とフォルダがあるので開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/004e4b3a-400b-1f39-07c4-af070cb9f8ce.png)

#### 引き継ぐメールを右クリックし「フォルダにコピー」を選択
既存のフォルダ、もしくは、新しいフォルダにメールを取り込みます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/236222/fbc64adc-02e3-8c20-74c4-6361548d8b41.png)

以上です。
必要に応じ「送信済みアイテム」などにも適用します。

取り込みが終われば、共有を解除できます。
Tailscaleを用いたWindows PCの遠隔操作について

# 問題
* 家からMacを使って、大学に置いてあるPCにアクセスしたい
* Mac側で使用するソフトはMicrosoft Remote Desktop
* しかし学校に置いてあるWindows PCは大学のネットワークを使っているので、Remote Desktopではアクセスすることが出来ない(ブロックされているみたい)
# 環境
* Windows PC側: Windows 11
* Mac側: Sequoia 15.0.1, Apple M2

# いろいろ試してみた。
以下のリンクに記述されていることを試してみたが、なかなか上手くいかなかった。
[Tailscaleで繋がらなくなったときにまずやること](https://qiita.com/mumoshu/items/344913544289606a10c0)
[Tailscaleで無料で簡単、VPNを構築するぞ](https://zenn.dev/0_0/articles/16975274aa3ba7)
[tailscale つながらない　そんな時は](https://ameblo.jp/ikeikemar/entry-12691817652.html)
[Tailscaleを使って研究室内のPCアクセスしようとしたら0x204が出た話](https://tech.ateruimashin.com/2021/05/tailscale%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%A0%94%E7%A9%B6%E5%AE%A4%E5%86%85%E3%81%AEpc%E3%82%A2%E3%82%AF%E3%82%BB%E3%82%B9%E3%81%97%E3%82%88%E3%81%86%E3%81%A8%E3%81%97%E3%81%9F%E3%82%890x204/)

# Mac側からPingコマンドで通信を確認
![096b0014f6aa-20240919.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/513172/0c17b5a6-7ccd-ac97-8623-85a660f141e9.png)
結果通信はうまくいっていることが確認できた。

# 実は別のVPNが通信を妨害していたかもしれない
Windows PC側を再起動し、デスクトップ画面が現れた瞬間だと一瞬Macから遠隔操作することが出来る。しかし5分程立つと接続が切れる。
ここで別のプロジェクトでNordVPNをWindows PC側で使ったことを思い出した。そしてこいつはPCが起動すると自動的に立ち上がることも思い出した。
確かVPNを2つ立てるとTailscaleが機能しなくなるという話を聞いたことがある。NordVPNを終了させると、Macから遠隔操作が出来る様になった。

# 後日談
諸事情があってWindows PCを初期化したら、またMacからRemote Desktopで繋げなくなりました。
この時はWindows PC側でRemoteデスクトップの設定をOnにするとうまくいきました。やり方は下記URL参照
[【PC】Windowsのリモートデスクトップを「有効」にするには](https://faq01-fb.fujifilm.com/faq/show/9873?site_domain=default)
３D画像fbxを開く方法

windowの3Dビューアで、拡張子fbxの画像を開くと、セキュリティ脆弱性のためひらくことができないと出る。

![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759593/b91d59f3-2f8e-0500-8780-3439df8f19af.png)

OKで、ダイアログを閉じる。

ヘルプタグ⇒設定をクリックする。
![タイトルなし１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759593/8122ed8b-8216-dae9-284f-3e716aaad328.png)


脆弱性を確認したうえで開く機能を「ON」にすると、開けるようになる。
![タイトルなし２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759593/29c73ef0-6e38-27dc-1c35-a3ac181e5e76.png)

[脆弱性の報告]
次の事象が報告されているので、開く機能をONにしてから、別のファイル形式で保存してから
fbxを開くを「OFF」にするほうがいいと思う。
![タイトルなし３.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2759593/2801c6af-3aba-2562-e8ed-d1470a7bed05.png)


以上。
Go言語のクロージャーとシャドーイングの影響

Golangにおけるクロージャーは、関数が他の関数のスコープ内で定義され、その外部の変数にアクセスできる機能を指します。これにより、関数内で外部の変数を保持したり、状態を持たせたりすることが可能になります。

### クロージャーの基本
クロージャーは、以下のように定義されます。

```go
package main

import "fmt"

func main() {
    x := 10
    increment := func() int {
        x++
        return x
    }

    fmt.Println(increment()) // 11
    fmt.Println(increment()) // 12
}
```

この例では、`increment`関数が`x`という外部変数にアクセスし、値をインクリメントしています。`increment`はクロージャーであり、`x`を「閉じ込めて」いるため、呼び出すたびに`x`の値が保持され、更新されます。

### シャドーイングの影響
シャドーイングは、同じ名前の変数が異なるスコープで再定義されることで発生します。Golangでは、内側のスコープの変数が外側のスコープの変数を隠します。これにより、意図しない動作を引き起こすことがあります。

以下にシャドーイングの例を示します。

```go
package main

import "fmt"

func main() {
    x := 10

    increment := func() int {
        x := 5 // ここでシャドーイングが発生
        x++
        return x
    }

    fmt.Println(increment()) // 6
    fmt.Println(x)           // 10 (外側のxは変更されていない)
}
```

この例では、`increment`関数内で新たに`x`が定義されているため、外部の`x`は影響を受けず、`increment`内での`x`は5から6に増加します。外部の`x`はそのまま10のままです。

### まとめ
- **クロージャー**は外部の変数にアクセスできる関数です。
- **シャドーイング**は、内側のスコープで変数名を再定義することで外側の変数に影響を与えない現象です。
- クロージャーを使用する際は、シャドーイングによる意図しない影響を考慮することが重要です。
Salesforce 認定Platformデベロッパー試験レポート

この記事は、先日「Salesforce 認定Platformデベロッパー試験」を受験し、
無事合格しましたので、そのレポートになります。

## 【目次】
1．勉強法について
2．正答率
3．まとめ

## 1．勉強法について
①模擬問題（Web）
私は業務である程度Salesforceに触れていたため、Web上にある模擬問題を中心に実施しました。
主に利用したサイトは下記の2つです。

・[TysonBlog](https://tysonblog-whitelabel.com/salesforce-dev-practice1)
社内の他受験者も利用していたサイトです。
数あるサイトの中でもかなり丁寧に解答、解説を記載してくれているので、他サイトで問題を解く前にまずはこちらを実施して、解説の内容を理解することを心掛けました。

・[JPN試験](https://www.jpnshiken.com/shiken/Salesforce.PDI-JPN.v2024-04-18.q110.html)
Platform アプリケーションビルダー試験を受験する際も利用したサイトです。
問題にはいくつかのバージョンがありますが、今回は最新のバージョン(v2024-04-18)を実施しました。
本番の試験でもこのサイトの問題と類似したものがいくつか出たので、実施しておいてよかったです。
ただし、サイト上に記載の解答は間違っているものも複数あり、ただ解答を鵜呑みにするのではなく、公式のHelpページ等を参照して、裏を取る必要があります。


②社内勉強会
週に一度開催されている社内でのSalesforce勉強会へ参加し、資格保有者の方からSalesforceの機能の説明や、模擬問題の解説をしてもらいました。
公式のHelpページだけではよく分からない機能の説明も、実例を交えて分かりやすく説明してもらえたので、勉強を進めるうえでの助けになりました。

## 2．正答率
冒頭で記載しましたが結果は合格で、正答率は下記表の通り大体85%と思われます。
合格ラインは68%のため、余裕をもって合格できました。

| 単元 | 配点（%） | 問題数（想定） | 得点数（想定） | 
|:-|:-:|:-:|:-:|
| 開発者の基本事項 | 23 | 14 |  10 |
| プロセスの自動化とロジック | 30 | 18 |  15 |
| ユーザーインターフェース | 25 | 15 |  14 |
| テスト、デバッグ、リリース | 22 | 13 |  12 |
| 合計 | 100 | 60 |  51 |

## 3．まとめ
今までに受けた試験（認定アドミニストレーター、アプリケーションビルダー）はいずれもギリギリ合格だったので、今回余裕をもって合格することが出来てよかったです。
今までの業務では宣言型の開発をメインで行ってきましたが、今後はプログラミング型の開発も行うようになるので、今回の勉強で得た知識を業務に活かしていきたいと思います。
Android 現場新参画者向けのキャッチアップサポート資料について

# 概要
新しい現場に参画する時、歴が浅いメンバー等は「どこからキャチアップして良いのか？」と疑問に思うメンバーがいると思います。
こういったメンバーにもなるべく早いキャチアップをしてもらう必要があると考えたため、新しい現場で以下が分かる簡単な資料を作成しました。

**資料から分かるようにした内容↓**
・ソースコードキャチアップの流れが分かる
・アーキテクチャを理解できる
・API接続からUI反映までの流れが理解できる

特にAPI接続からUI反映までの流れがわかってしまえば最低限のキャッチアップはできると考えたため、そこの内容を重点的に作成しました。
下記に、その当時作成した資料を展開。

# 当時の資料
以下から当時の資料(クラス名やパス名等は省略しております。)↓↓↓

------

* **Androidキャッチアップ観点**
    * **言語は何か？**
        * kotlin
    * **UIは何を使用しているか？**
        * Android view
        * Jetpack Composeは未使用
    * **アプリ初回起動時の処理、最初の画面はどこか？**
        * 初回起動： 〇〇Application
            * SDK関連の設定等を行なっている
            * Applicationクラスを継承
        * 最初の画面：〇〇Activity
    * **アーキテクチャは何を使用しているか？**
        * Google推奨アーキテクチャ × MVVM
            * Dataレイヤー：通信等のデータのやりとりを行うレイヤー
            * Domainレイヤー：ビジネスロジックを担当しているレイヤー
            * Presentationレイヤー：UIを担当しているレイヤー
        * アーキテクチャ分解
            * **どこで画面表示をしているか？**
                * presentationディレクトリ
                    * Activity, Fragment
            * **どこでUIロジックを処理してるか？**
                * presentationディレクトリ
                    * viewModel
            * **どこにビジネスロジックがあるか？**
                * domainディレクトリ
                    * usecase
            * **どこでAPI連携を行なっているか？**
                * dataディレクトリ
                    * APIロジック呼び出し箇所：〇〇.kt
                    * API接続：〇〇.kt
                        * Retrofit使用
        * **分解したアーキテクチャは、今の現場だとどこのディレクトリになるか？**
            * 画面表示
                * ディレクトリ記載
            * UIロジック処理
                * ディレクトリ記載
            * ビジネスロジック
                * ディレクトリ記載
            * API連携
                * ディレクトリ記載
        * **DIは、何のライブラリを使用しているか？**
            * hilt

**API接続図**
下記では、API接続図を展開

![スクリーンショット 2024-10-09 11.26.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/677032/58e24938-0af2-c92a-a8cd-8d0b0d7f892e.png)

----

# まとめ
まだまだ、改善の必要がある内容ですが、新しく参画したメンバーから「キャッチアップはスムーズにできた」とお声がけもいただいたので、無いよりはあったほうが良いなと思いました。
【DAY30】OSI参照モデルについて

## OSI参照モデルとは
OSI（Open Systems Interconnection）参照モデルとは、国際標準化機構が策定したネットワーク標準規格です。コンピューターネットワークに求められる通信機能を7階層の構造に分割し定義しています。
元々はメーカーごとに自由にルールを作って機器間の通信を行っていました。しかし、それでは異なるメーカーの機器と通信が取れないため、国際標準化機構が共通の約束事を定めました。それがOSIです。

## OSI参照モデルの階層
OSI参照モデルは、以下の7つの階層に分けられています。

第7層：アプリケーション層
第6層：プレゼンテーション層
第5層：セッション層
第4層：トランスポート層
第3層：ネットワーク層
第2層：データリンク層
第1層：物理層

## アプリケーション層
第7層のアプリケーション層では、ソフトウェアの通信規則、つまりソフトウェアが提供する機能についての使用や通信手順、データ形式などを定めています。例として、Webページを閲覧するときのHTTP、メールを受信するときのPOPなどが挙げられます。
利用するアプリケーションに応じてハードウェアの通信機能でプロトコルの制御を行います。
## プレゼンテーション層
第六層のプレゼンテーション層では、コンピュータとネットワークのデータ形式の変換について定義しています。例として、電子メールを転送する際のSMTP、ファイルを転送する際のFTPなどがあります。
例えば、HTMLファイルをブラウザに表示する時には、FTPで送られてきたHTMLファイルに対し、Webサーバで文字コードや改行コードをもとに適切な形式で表示するための変換を行います。ファイルにおけるデータの表現形式を定義しているため、文字化けなどをすることなくこの変換が行われます。

## セッション層
セッション層では、ホスト（サーバやパソコンなどの端末）間の通信の確立、維持、終了の流れに関する規格を定めています。例として、安全に通信をするためのセキュリティプロトコルであるTLSが挙げられます。

## トランスポート層
トランスポート層では通信を制御し目的に応じた通信を行います。代表的なものとして、信頼性は高いが通信速度が遅いTCP、信頼性は低いが通信速度が速いUDPが挙げられます。

## ネットワーク層
ネットワーク層では、データを送る相手を決め最適な経路で送信します。代表的なものとしてIPがあります。IPアドレスを接続するコンピュータ機器に付与し機器同士を通信することで用いられます。これで直接繋がっていないネットワーク機器間でもやり取りができます。

## データリンク層
データリンク層とは通信回線のことを指し、隣接する機器同士の通信を実現します。代表的なものにEthernetがあります。Ethernetは有線LANの標準の一つです。

## 物理層
物理層は物理的な接続（ケーブルやコネクタなど）を定めるものです。
Databricksクイックスタートを使ってみた

# 初めに
Databricksを初めて触るので、AWSで環境を構築してみました。
その際、クイックスタートありましたのでAWSでの構築を実施する際の参考になればと思います。
※今回はCloudformationを利用しています

# 事前に必要なこと
①Databricksのアカウントオーナー用のアカウント
　※事項で詳細に説明いたします
②AWS管理者権限
 →AWSの管理者権限を持つIAMユーザー
③利用するクラウドとリージョンの選択
→今回は東京リージョンで選択しています

# 環境構築手順
### ①Databricks社の無料トライアルサイトに登録
自分の名前を登録し、必要な情報を入力して送信します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/d0dbe5db-6903-4691-360a-4877193807d9.png)

### ②プロバイダの選択
今回はAWSを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/d35a207c-5703-fa7b-3e55-6dd507d9c9a8.png)


### ③メールの確認
2通メールが届きます
”Welcome to Databricks!”と記載があるメールに記載のある本文中のリンクにアクセスを実施します。

### ④パスワードの再設定
登録したアドレスに紐づくパスワードを設定します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/19ccc5cb-f70f-811b-9003-253cfb9df903.png)

### ⑤ワークスペース名とリージョンの選択
自身でワークスペース名とリージョンを選択します
ワークスペース名は任意で、リージョンは今回東京を選択しました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/0e1049af-c39d-b2cc-e562-14ec2ba2bca1.png)
リージョンなど選択後、”クイックスタートを始める”をクリックします

### ⑥AWS側の作業
AWSにログイン後、クイックスタートの画面に遷移します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/26373056-02f3-17d0-47b5-d0965e9e2994.png)

”AWS CloudFormationによってIAMリソースがカスタム名で作成される可能性があることを承諾します。”のオプションにチェックし、”スタックの作成”をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/3fbbfb5a-879d-6b50-b42e-fa7a1ec65b31.png)

Stackの画面が表示されるので、設定完了を待ちます
※10分ほどで完了しました。
完了後はステータスがCreate_Completeと表示されます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/78247347-a744-a972-399f-e440110a42a1.png)
こちらの作業により、Databricksのワークスペース（VPC/S3など）が作成されておりました

### ⑦Databricksにアクセス
Databricksのアカウントコンソールにアクセスし、ワークスペースに移動します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/8e2a8a8f-630d-84f2-c898-680b1456c8f0.png)
※もしくは、登録したメールアドレス宛にワークスペース作成完了後メールが届きますので、そちらからでもアクセス可能です
<br>
その後、ログイン画面が表示されるので設定したメールアドレスとパスワードでログインし、ワークスペースが表示されたらDatabricksの環境構築は完了です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3901772/244816a9-ded6-853f-70e3-b00157fd54a2.png)

Totalで1時間いかないぐらいで設定は完了しました。
ここからはDatabricksの操作感や実際の動きなどを見ていこうと思います。
※参考：https://docs.databricks.com/ja/admin/workspace/quick-start.html
Android StudioでGithub連携で手こずった

### ［困ったこと］
### リモートリポジトリを操作しようとすると「Permission denied (publickey)」エラーになる

### ［解決策］
### remote.origin.urlを正しく設定する
コマンドラインでGithubを操作していました。Android Studioからプラグインで操作できるので便利だと思い使ってみましたが最初にエラーで困った件です。
手順通りにGithubでトークンを発行しAndroid Studioに設定。特に難しいことは無さそうです。ところがAndroid Studioからリモートリポジトリを操作しようとするとエラーになります。
``` :エラー
git@github.com: Permission denied (publickey).
```
トークンの再発行、gitのやり直し...何回やっても同じ。もう諦めようかと思った時ふと疑問が。そもそもこのエラーは公開鍵認証のsshログイン時によく見るもの。Android Studioはどこからユーザー名を持って来るのか。どうやってGithubに接続するのか。Android StudioのGithubの設定にはありません。またGithubをアクセスするurlもどこから持って来るのか。と言うことはgitの設定から持ってくるのでしょう。
``` :gitの設定確認
git config --list
```
問題はremote.origin.urlでした。
私は元々Githubにssh+公開鍵でログインして操作していました。このためssh用の設定が保存されていました。これをhttps用に書き換えたら上手く行きました。
設定は下記コマンドで行いました。
``` :gitの設定
git config --edit
```
Amazon EC2 Auto Scalingのスケーリングポリシーをまとめてみた

AWSのAmazon EC2 Auto Scalingを使うと、トラフィックの変動に合わせてインスタンス（仮想サーバー）の数を自動で増減できます。これにより、パフォーマンスを維持しつつ、コストを最適化できるのが大きなメリットです。
スケーリングポリシーという、インスタンスの数をどう増減させるかを制御するルールについて、初心者向けにまとめみた

### スケーリングポリシーとは？

スケーリングポリシーは、Auto Scalingグループ内のインスタンス数を自動で増減させるための設定です。適切なスケーリングポリシーを使うことで、トラフィックが増えてもシステムが対応できるようにし、不要なリソースを減らしてコストを抑えることができます。

### スケーリングポリシーの種類

### 1. 手動スケーリング

	•	概要: 手動でインスタンス数を増やしたり減らしたりします。
	•	特徴: 自分で設定するので、細かいコントロールが可能ですが、トラフィックの急な変動には対応できません。
	•	使う場面: 一時的に増減させたい場合や、事前にトラフィックを予測できる場合に便利です。

### 2. シンプルスケーリングポリシー

	•	概要: 1つのトリガー（例：CPU使用率が70％を超えたら）に基づいて、インスタンスを増減します。
	•	特徴: 簡単に設定できますが、短期間でのトラフィック変動には対応しにくいです（クールダウン期間という待機時間があるため）。
	•	使う場面: 定期的にトラフィックが変動するような場合に向いています。

### 3. ステップスケーリングポリシー

	•	概要: メトリクス（例：CPU使用率）に応じて、段階的にインスタンス数を増減します。
	•	特徴: トラフィックの変動に合わせて細かく対応でき、複数の条件を設定可能です。
	•	使う場面: トラフィックの変動が予測しづらい場合や、より細かい調整が必要な場合に役立ちます。

### 4. ターゲット追跡スケーリングポリシー

	•	概要: 指定したターゲット（目標）を維持するようにインスタンス数を自動調整します。例えば、「平均CPU使用率を50％に保つ」と設定します。
	•	特徴: 自動で最適なインスタンス数を調整してくれるため、最も簡単で効果的です。また、クールダウン期間がないのも便利です。
	•	使う場面: 初心者には一番おすすめのポリシーで、システム負荷に合わせて自動的にインスタンスを調整したい場合に最適です。

### 5. スケジュールスケーリングポリシー

	•	概要: 特定の日時にインスタンス数を増減します。例えば、朝8時にインスタンスを5台に増やし、夜8時に3台に減らす、といった設定が可能です。
	•	特徴: 予測できるトラフィックの変動に対して、事前にスケジュールを組むことができます。
	•	使う場面: 業務時間に合わせてインスタンスを増減させたり、季節的なトラフィック変動に対応する場合に使います。

### スケーリングポリシーの比較表まとめ
| 1 | 2 | 3 | 4 |
|:-:|:-:|:-:|:-:|
|ポリシータイプ|特徴|メリット|デメリット|
|手動スケーリング|手動でインスタンス数を変更|簡単で直接制御できる|自動化されていない|
|シンプルスケーリング|単一のトリガーに基づいて増減|設定が簡単|クールダウン期間が必要|
|ステップスケーリング|段階的にスケーリング|柔軟なトラフィック変動に対応可能|設定がやや複雑|
|ターゲット追跡スケーリング|目標値に応じて自動調整|最も自動化され、クールダウン不要|設定した目標値が適切である必要|
|スケジュールスケーリング|事前に設定したスケジュールで増減|定期的なトラフィックに対応可能|突発的なトラフィックには対応不可|
【2024年10月版】ProxmoxのCephのWARNをリセットするメモ【Proxmox, Ceph】

# はじめに

Proxmoxで構築しているクラスタ上のCephがWARNだしてる。。。

```terminal
# ceph -s
  cluster:
    id:     ********-f929-433a-8eb4-68c817d7f51f
    health: HEALTH_WARN
            1 mgr modules have recently crashed
```

該当のノード（pve4）でリセットしよ

```
# systemctl restart ceph-mgr@$(hostname -s)
```

あれ、WARNきえない。。。

```terminal
# ceph -s
  cluster:
    id:     ********-f929-433a-8eb4-68c817d7f51f
    health: HEALTH_WARN
            1 mgr modules have recently crashed
```

となったときのメモ

# 作業

## 状況を確認する

```terminal
# ceph -s
  cluster:
    id:     ********-f929-433a-8eb4-68c817d7f51f
    health: HEALTH_WARN
            1 mgr modules have recently crashed
```

## クラッシュリストの表示

```terminal
# ceph crash ls
ID                                                                ENTITY    NEW  
2024-10-01T04:14:05.218890Z_69989027-cbe2-4139-8230-************  mgr.pve4   *   
```

## クラッシュリストから削除

```terminal
# ceph crash rm 2024-10-01T04:14:05.218890Z_69989027-cbe2-4139-8230-************
```

## 削除を確認

```terminal
# ceph crash ls
#
```

## 削除後の状況を再確認

```terminal
# ceph -s
  cluster:
    id:     ********-f929-433a-8eb4-68c817d7f51f
    health: HEALTH_OK
```

# さいごに

かんたんでしたね