OmniAICreator/Qiita-1.07M huggingface dataset:
副作用との向き合い方：Effectを分離して制御する戦略


## 概要

関数型プログラミング（FP）において「副作用（Side Effect）」は設計上の**最大の敵**である。  
だが同時に、**副作用を完全に排除することは不可能**でもある。

ではどうするべきか？

答えはシンプルだ。  
> **副作用を“抑圧”するのではなく、“分離”し、“制御下”に置く。**

本稿では Scala を例に、IO・ログ・例外・状態変更といった副作用をどのように扱い、  
どのように構造的に「隔離」するのかを設計の観点から論理的に解説する。

---

## 1. 副作用とは何か？

### ✅ 定義：
> **外部の状態を変更する、あるいは外部の状態に依存する処理**

### 例：

- ファイルの読み書き
- コンソール出力（`println`）
- DB操作・ネットワークアクセス
- 乱数・現在時刻取得（非決定性）

---

## 2. なぜ副作用が問題なのか？

| 問題点             | 説明                                                                 |
|--------------------|----------------------------------------------------------------------|
| **テスト困難**      | 同じ入力でも出力が変わる＝**再現性の欠如**                         |
| **デバッグ困難**    | 状態がどこで・いつ変わったかが曖昧                                  |
| **並行処理の危険性** | 複数スレッドで副作用が衝突 → **データ破壊や不整合が発生**          |
| **設計の非純粋化**   | 副作用の混入によりロジックがブラックボックス化し、**再利用性が落ちる** |

---

## 3. 解法：Effectを「分離」して「扱う」

Scalaにはこの問題に対して明快な解法がある：

> **IO（副作用）を値として扱う。**  
> **Effectを構造として管理する。**

---

## 4. 実装例：`IO` モナドによる副作用の構造化

```scala
import cats.effect.IO

def readLine: IO[String] = IO(scala.io.StdIn.readLine())
def printLine(msg: String): IO[Unit] = IO(println(msg))

val program: IO[Unit] = for {
  _ <- printLine("名前を入力してください：")
  name <- readLine
  _ <- printLine(s"こんにちは、$name さん！")
} yield ()
```

- **副作用は即座に実行されない**（遅延評価）  
- **純粋関数の中に副作用を“値”として閉じ込める**

---

## 5. 設計意図：Effectful と Pure の分離

```text
[pure]     validateName(name: String): Either[Error, Name]
[effect]   readLine(): IO[String]
[effect]   printLine(msg: String): IO[Unit]
```

- **純粋ロジック**（検証や加工）と  
- **Effectfulロジック**（入出力や保存）を**レイヤーで分ける**

→ これによりテストは Pure 部分だけで済み、**Effectは統合テストの責務へと移動する**

---

## 6. 設計判断フロー

```text
① この処理は副作用を含むか？ → YES → IOで包んで明示的に扱う

② 処理の本質は値の変換か？ → YES → 純粋関数として切り出す

③ いつ副作用が実行されるか制御できているか？ → YES → 安定性が高い

④ 副作用の結果に依存しているロジックがあるか？ → 分離して境界を定義する
```

---

## よくある誤解と対策

### ❌ 副作用は完全に排除すべき？

→ ✅ **No。副作用は「必要」だが「無制御で混在」させるべきではない**

---

### ❌ IOで包むだけでテスト可能になる？

→ ✅ **テストは副作用の外側（純粋関数部分）で済ませるのが理想**  
→ ✅ IO自体のテストにはモック・テストランナーが必要になる

---

### ❌ Effectと純粋関数の境界が曖昧

→ ✅ 明確に分けて、「境界はインターフェースとして明示」すべき

---

## 結語

関数型プログラミングは副作用を排除しない。  
それは**副作用を“明示的に分離し、構造的に制御する思想”**である。

- 副作用を「値」として管理し  
- 実行タイミングを「制御可能」にし  
- 設計の中で「安全に」組み込めるようにする

**関数型設計とは、  
“世界を変える行為を、構造の中で閉じ込め、予測可能性に従わせる技術である。”**
高階関数：関数を操作する関数で設計を開く


## 概要

**高階関数（Higher-Order Function）**は、関数型プログラミングの根幹をなす考え方である。  
関数を「引数」として扱い、「戻り値」として返すことで、ロジックを動的に構築できる。

この仕組みは**制御の抽象化・再利用性・柔軟な設計**を可能にし、  
「関数＝値」というパラダイムを支える力そのものだ。

本稿では TypeScript をベースに、**高階関数の設計的意義と実装応用**を明快に解説する。

---

## 1. 高階関数とは何か？

> **関数を引数にとる、または関数を返す関数**

```ts
function withLogging<T>(fn: (arg: T) => T): (arg: T) => T {
  return (arg: T) => {
    console.log('Before:', arg)
    const result = fn(arg)
    console.log('After:', result)
    return result
  }
}
```

- `withLogging` は関数を引数として受け取り、**拡張された関数**を返す  
- ロジックに「追加の振る舞い」を注入できる

---

## 2. 実用例①：ロジックのラッピング

### バリデーションロジックを共通化する

```ts
function validate<T>(fn: (arg: T) => void): (arg: T) => void {
  return (arg: T) => {
    if (arg == null) throw new Error('Input is null or undefined')
    fn(arg)
  }
}

const saveUser = validate((user: { name: string }) => {
  console.log(`Saving ${user.name}`)
})

saveUser({ name: 'Alice' }) // OK
saveUser(null) // throws
```

- どんな処理にも **「共通の前処理」** を差し込める  
- 抽象化されたパターンが**設計を開放的にする**

---

## 3. 実用例②：関数生成（関数を返す）

```ts
function makeMultiplier(factor: number): (x: number) => number {
  return (x: number) => x * factor
}

const double = makeMultiplier(2)
const triple = makeMultiplier(3)

double(4) // => 8
triple(4) // => 12
```

- パラメタライズされた関数を**動的に生成できる**
- **依存や振る舞いを閉じ込めた小さな関数を量産可能**

---

## 4. 実用例③：カリー化（Curry）

```ts
function curry<A, B, R>(fn: (a: A, b: B) => R): (a: A) => (b: B) => R {
  return a => b => fn(a, b)
}

const add = (a: number, b: number) => a + b
const curriedAdd = curry(add)

const add5 = curriedAdd(5)
add5(3) // => 8
```

- 高階関数の応用で、関数の**部分適用**が可能になる
- 設計の流動性が高まる

---

## 5. 設計判断フロー

```text
① この処理は共通化できるパターンか？ → YES → 高階関数でラップ可能

② ロジックの一部だけを注入したいか？ → YES → 関数を引数として受け取る設計に

③ 関数を返すことで使い分けたいか？ → YES → クロージャとして設計

④ 多段階の変換があるか？ → YES → Curry・Composeと組み合わせる
```

---

## よくある誤解と対策

### ❌ 「高階関数は読みづらい」

→ ✅ **関数名と責務を明確に定義**すれば、むしろ処理の流れが見通しやすくなる

---

### ❌ 「ただの関数の入れ子と何が違うの？」

→ ✅ 高階関数は**関数レベルでの設計テンプレート**。設計を抽象化するための枠組み

---

### ❌ 「使いこなせるのは上級者だけ」

→ ✅ `map`, `filter`, `reduce` は**全て高階関数**。身近に使われている技術

---

## 結語

高階関数とは、関数を操作対象とすることで**設計そのものを柔軟にする抽象機構**である。

- 関数を受け取り、振る舞いを拡張し  
- 関数を返し、構成と依存を分離し  
- 関数を束ね、流れるような設計へと昇華する

**関数型設計における高階関数とは、  
“静的なロジックを、動的な構成可能性へと解き放つ構文的構造化である。”**
Integer.sqrt(4503599761588224)**2 > 4503599761588224

（確認した Ruby バージョン： 3.2.2, 3.3.7）

節目の AtCoder Beginner Contest 400 に Ruby で参加したら、C問題で謎のWAになって苦しんだ。

https://atcoder.jp/contests/abc400/tasks/abc400_c

[解説のひとつ](https://atcoder.jp/contests/abc400/editorial/12633)にもある平方根で解く方法を選んだ。浮動小数点数による誤差が危険だが、 Ruby だと [Integer.sqrt](https://docs.ruby-lang.org/ja/latest/method/Integer/s/sqrt.html) というメソッドで回避できる。

…のに正解にならない。さんざん悩んだ末に、自力で二分探索して平方根を計算するように変えたところ正解になった。

---

コンテスト後に解説を読んで、考え方は妥当だったとわかったため、何の平方根を求める際に間違えたのか調べた。その結果 `Integer.sqrt(4503599761588224)` が正しい値を返していない（小数を切り上げている）ことがわかった。

この値を検索したところいくつかページがヒットした。浮動小数点数による計算でずれるのは仕方ないとして、 sympy の isqrt でも同じ問題があったことが目に留まった。

https://github.com/sympy/sympy/issues/17034

比較的小さい入力に対しては isqrt の内部で浮動小数点数の sqrt を利用して高速化しているため、結果的にずれる可能性があるらしい。（十分に小さい入力であれば大丈夫）

---

Ruby のソースコードは確認できていないが、実際に誤った値を返す場合があることはわかった。エッジケースとして狙い撃ちされたら死ぬので、当面は Integer.sqrt を過信しないように注意する必要がある。
関数合成とパイプライン設計：ロジックをつなぐという発想


## 概要

関数型プログラミングにおける最大の美学の一つは、**「関数をつなぐ」という設計感覚**である。  
それは関数を独立した単位として設計し、それらを合成しながら全体の振る舞いを構築するというスタイルだ。

本稿では、F# を例に取り、関数合成とパイプラインの概念を明確化しつつ、  
**可読性・再利用性・拡張性を高める実装アプローチ**としての価値を提示する。

---

## 1. 関数合成とは何か？

> **関数合成（Function Composition）**とは、複数の関数を「つなげて新しい関数を作る」手法。

```fsharp
let f x = x + 1
let g x = x * 2

let h = f >> g  // まず f, 次に g を実行
```

```fsharp
h 3  // => (3 + 1) * 2 = 8
```

- `>>` は「順方向の関数合成」  
- `<<` は「逆方向（数学的な合成）」もサポート

---

## 2. パイプライン演算子 `|>` の設計思想

> パイプラインは、**値を関数に順次“流し込む”構文**

```fsharp
let result =
    3
    |> f   // 3 + 1 = 4
    |> g   // 4 * 2 = 8
```

- 処理の順番が **「データフローとして可視化される」**
- 実行順とコードの記述順が一致し、直感的に読める

---

## 3. パイプライン設計が強力な理由

| 利点             | 内容                                                  |
|------------------|-------------------------------------------------------|
| **可読性**        | 手続き的コードよりも、**処理の流れが直線的に見える** |
| **再利用性**      | 関数が独立しているため、どこでも組み合わせられる     |
| **宣言的構造**    | 「どう処理するか」ではなく「何をしたいか」が明確     |
| **柔軟な拡張性**  | 関数を差し込む・入れ替えるだけで振る舞いを変更可能   |

---

## 4. 関数合成 vs パイプラインの使い分け

| スタイル    | 使用場面                                   |
|-------------|--------------------------------------------|
| `>>` / `<<` | **関数自体を合成したいとき**                |
| `|>`        | **値の処理フローを記述したいとき**          |

---

## 5. 実例：データ加工処理をパイプラインで設計

```fsharp
let trim (s: string) = s.Trim()
let toLower (s: string) = s.ToLower()
let removeSpaces (s: string) = s.Replace(" ", "")

let normalize =
    trim
    >> toLower
    >> removeSpaces

let result =
    "  Hello World  "
    |> normalize   // => "helloworld"
```

- 各関数は小さく、テストしやすく、再利用しやすい  
- 振る舞いは合成され、最終的に一貫した出力が得られる

---

## 6. 設計判断フロー

```text
① この処理は複数ステップの変換を含むか？ → YES → 関数分割 + 合成

② 関数は値の変換に徹しているか？ → YES → 合成可能性が高い

③ 読みにくいチェーンがあるか？ → YES → `>>` または `|>` に切り替え

④ 途中に条件分岐や副作用が混ざっていないか？ → YES → 抽出して制御する
```

---

## よくあるミスと対策

### ❌ 全てのロジックを1つのパイプに詰め込む

→ ✅ 各関数の責務が不明瞭になる。**関数分割して合成する**

---

### ❌ 合成対象の関数が「値を返さない」

→ ✅ **パイプラインでは“値を返す関数”のみをつなげるべき**

---

### ❌ 副作用（IO、ログ出力など）を途中に挟む

→ ✅ **副作用は末端に限定するか、効果を明示して扱う**

---

## 結語

関数合成とパイプライン設計は、  
「ロジックを部品化し、構造として繋ぎ、再構成可能なシステムへと昇華する手法」である。

- 複雑な処理を**小さな関数に分割**し  
- 意図した順序で**合成**し  
- **宣言的かつ柔軟に再構築**できるようにする

**関数型の合成とは、  
“ロジックを部品として再定義し、意図をフローとして構築する構造設計の技術である。”**
kintoneのステータス変更をじぶんページに通知するJavaScriptコードを作ってみた

## はじめに

kintoneのじぶんページプラグインでは、レコードのステータス変更を通知する機能が標準では提供されていません。
この記事では、ステータス変更時に自動でコメントを追加することで、じぶんページへの通知を実現するJavaScriptコードを紹介します。

## 背景

kintoneのじぶんページプラグインでは、以下の2つの場合のみ通知が送られます：

1. 新規レコードが作成された時
2. コメントが投稿された時

しかし、業務上、**ステータスの変更**も重要なイベントとして通知したいケースが多々あります。
例えば：
- 申請が承認された時
- タスクが完了した時
- 案件がクローズされた時

## 解決方法

この問題を解決するために、**ステータスが変更された時に自動的にコメントを追加する**JavaScriptコードを開発しました。
これにより、じぶんページプラグインの標準機能を活用しながら、ステータス変更の通知を実現できます。

## プラグインの特徴

- ステータス変更時の自動コメント投稿
- じぶんページ通知との連携
- シンプルな設定
- エラーハンドリング機能
- ドキュメント化されたクリーンなコード

## 使い方

### 1. インストール

1. [GitHubリポジトリ](https://github.com/yakiimo-bsp/kintone-status-change-comment)から`status-change-comment.js`をダウンロード
2. kintoneの設定画面で、「JavaScript / CSSのカスタマイズ」を開く
3. JSファイルをアップロード
4. 保存

![kintoneのJavaScript/CSSカスタマイズ設定画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651633/9c8d7e29-be01-4c48-b1d1-b46fb9d93b54.png)
*JavaScript/CSSカスタマイズ画面でJavaScriptファイルをアップロード*

### 2. 動作確認

デフォルトでは以下のステータス変更を検知します：
- "accepted"を含むステータスに変更 → "The status has changed to 'Accepted'"というコメントが追加
- "closed"を含むステータスに変更 → "The status has changed to 'Closed'"というコメントが追加

![ステータス変更時のコメント投稿例](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651633/c9317418-2cf1-47a9-b4b4-c4cab01d9391.png)

*ステータスが変更されると自動的にコメントが追加され、じぶんページに通知される*

### 3. カスタマイズ

監視するステータスとコメントの内容は、コード内の`STATUS_CONDITIONS`オブジェクトで管理しています：

```javascript
const STATUS_CONDITIONS = {
    ACCEPTED: {
        condition: 'To Accepted',
        toStatusContains: 'accepted',
        commentText: 'The status has changed to "Accepted".'
    },
    CLOSED: {
        condition: 'To Closed',
        toStatusContains: 'closed',
        commentText: 'The status has changed to "Closed".'
    }
};
```

新しいステータス条件を追加する場合は、このオブジェクトに設定を追加するだけです。

## 技術的な詳細

### 使用している技術
- 言語: JavaScript
- kintone API バージョン: v1
- イベント: `app.record.detail.process.proceed`

### エラーハンドリング
- コンソールにログを出力
- エラー発生時のメッセージ表示
- 一部のコメント投稿が失敗しても継続して動作

### コードの特徴
- モジュラーな設計
- 詳細なJSDocコメント
- 設定の一元管理
- Promise.allによる効率的な非同期処理

## 今後の展望

現在検討している機能拡張：
1. コメントテンプレートのカスタマイズ機能
2. 通知先ユーザーの制御機能
3. 複数のステータス条件のグループ化

## まとめ

このJavaScriptコードを使用することで、kintoneのじぶんページプラグインの制限を克服し、ステータス変更の通知を実現できます。
シンプルな実装ながら、実用的な機能を提供しています。

## 参考リンク

- [GitHubリポジトリ](https://github.com/yakiimo-bsp/kintone-status-change-comment)
- [kintone API リファレンス](https://developer.cybozu.io/hc/ja/articles/201941954)

## 環境
- kintone
- JavaScript
- じぶんページプラグイン
[Python] フォントの情報を取得する

# はじめに

等幅フォントを使っていてもUnicodeの文字列が綺麗に揃わないのでフォントの横幅を知りたいと思いました。
調べた結果、Pythonで簡単に取得できる方法がありましたので記事にしてみました。

# 環境

```:OS
Windows 11 Pro
```

```:py -VV
Python 3.12.0 (tags/v3.12.0:0fb18b0, Oct  2 2023, 13:03:39) [MSC v.1935 64 bit (AMD64)]
```

# コード

```python:python
import argparse
from pathlib import Path

from fontTools import ttLib

NoBreakSpace = "\u00a0"


def argumentParser():
  parser = argparse.ArgumentParser()
  parser.add_argument("inputPath", type=Path, help="input path")
  parser.add_argument("-a", "--showArgument", action="store_true", help="show arguments.")
  return parser.parse_args()


def dump(font, output):
  glyphSet = font.getGlyphSet()
  cmap = font.getBestCmap()
  with output.open("w", encoding="utf-8") as file:
    file.write(f"number = {len(cmap)}\n")
    for codePoint, name in cmap.items():
      g = glyphSet[name]
      c = f"|{NoBreakSpace}{chr(codePoint)}{NoBreakSpace}|"
      h = g.height
      h = h if h is not None else ""
      string = f"{name:20}, {codePoint:6x}, {g.width:4}, {h:4}, {c}\n"
      file.write(string)


if __name__ == "__main__":
  args = argumentParser()
  if args.showArgument:
    print(args)

  Path("font").mkdir(exist_ok=True)
  
  if args.inputPath.suffix == ".ttf":
    output = Path(f"./font/{args.inputPath.stem}.txt")
    with ttLib.TTFont(args.inputPath) as font:
      dump(font, output)

  if args.inputPath.suffix == ".ttc":
    for i, font in enumerate(ttLib.ttCollection.TTCollection(args.inputPath)):
      output = Path(f"./font/{args.inputPath.stem}{i}.txt")
      dump(font, output)
```

フォントの情報を取得するために"fontTools"を使いました。

始めに、`ttLib.TTFont(path)`へフォントファイル(`.ttf`)のパスを渡してフォントの情報が入ったTTFontオブジェクトを取得します。

次に、TTFontオブジェクトから`getGlyphSet()`を使って全てのグリフ情報が入ったオブジェクト(TTGlyphとしておきます)を取得します。
このTTGlyphオブジェクトからグリフの情報を得るにはグリフの名前が必要です。

そこで、`getBestCmap()`を使い、Cmap(Character Map)を取得します。
これは、キーがUnicodeのコードポイントで、値がコードポイントに対応するグリフの名前である辞書を返します。
得られた名前を使ってTTGlyphにアクセスすればグリフの情報が手に入ります。

```python
with ttLib.TTFont(args.inputPath) as font:
  glyphSet = font.getGlyphSet()
  cmap = font.getBestCmap()
  for codePoint, name in cmap.items()
    g = glyphSet[name]
```

以下は、出力例です。
実際の出力から制御文字を削除しています。

```:出力例
number = 16127
uni0000             ,      0,    0,    0, | |
uni000D             ,      d,    0,    0, | |
space               ,     20,  128,  256, |   |
exclam              ,     21,  128,  256, | ! |
quotedbl            ,     22,  128,  256, | " |
numbersign          ,     23,  128,  256, | # |
dollar              ,     24,  128,  256, | $ |
percent             ,     25,  128,  256, | % |
ampersand           ,     26,  128,  256, | & |
quotesingle         ,     27,  128,  256, | ' |
parenleft           ,     28,  128,  256, | ( |
parenright          ,     29,  128,  256, | ) |
```

# 参考

https://fonttools.readthedocs.io/en/latest/ttLib/ttFont.html

https://fonttools.readthedocs.io/en/latest/ttLib/ttCollection.html
日付フォーマット用ライブラリの選定

# 日付を扱うために
個人で開発しているアプリで日付を扱う必要があり,
ライブラリを導入することにしました。

## 候補１ moment.js
mutable(変更する際は元の変数を書き換える)
### メリット
* 豊富な機能：日付の加算や減算、フォーマット、相対日時、ローカライズなど、多くの機能

### デメリット
* 2020年以降、使用は非推奨
* ローカルタイムを表示するためには、プラグインを導入する必要がある

| スター数 | 最終更新日 | ファイルサイズ| 確認日|
|:-:|:-:|:-:|:-:|
|  48.1k |  2023-12-27 | 2kb  | 2025/3/10 |

```js
import moment from 'moment';

let newDate: moment.Moment =
  newDate: moment().add(1, 'days'); // 一日加算
```
公式github
https://github.com/moment/moment

## 候補2 day.js
Immutable（変更する際は、新しい変数に格納。変更するごとに変数が増える。新しく変数を作成し、最新のものを読み取るメゾットが必要。）

### メリット
* 軽量
* 全てのブラウザで対応
* 必要な機能だけを追加できるプラグインシステム

### デメリット
* ローカルタイムを表示するためには、プラグインを導入する必要がある

| スター数 | 最終更新日 | ファイルサイズ| 確認日|
|:-:|:-:|:-:|:-:|
|  47.5k |  2024-08-20 | 2mb  | 2025/3/8 |

```js
import dayjs from 'dayjs';

let currentDate: DateTime = dayjs()
let newDate: DateTime =
  newDate: dayjs().add(1, 'day'); // 一日加算
```
公式github
https://github.com/iamkun/dayjs

## 候補3 date.fns
Immutable
### メリット
* 多くの日付操作機能がある
* 個別の関数で処理を行い、必要な処理だけを取り込めるため、非常に軽量
* 型定義が充実

### デメリット
* ローカルタイムを表示するためには、プラグインを導入する必要がある

| スター数 | 最終更新日 | ファイルサイズ| 確認日|
|:-:|:-:|:-:|:-:|
|  35.4k |  2024-09-17 | 22.6 MB  | 2025/3/8 |

```js
import { addDays } from 'date-fns';

let currentDate: Date = new Date();
let newDate: Date = addDays(currentDate, 1);
```
公式github
https://github.com/date-fns/date-fns

## 候補４ Luxon.js
monent.jsの後続として開発。
Immutable

### メリット
* ローカルタイムがプラグインをいれなくとも、利用できる
* 複数のローカルタイムに対応

### デメリット
* ファイルサイズが大きい。（処理が重くなる）
* ローカルタイムを使用しない場合は過剰

| スター数 | 最終更新日 | ファイルサイズ| 確認日|
|:-:|:-:|:-:|:-:|
|  15.7k |  2024-08-04 | 4.48 MB  | 2025/3/8 |

```js
import { DateTime } from 'luxon';

let currentDate: DateTime = DateTime.now(); // 現在の日付
let newDate: DateTime = 
  newDate: currentDate.plus({ days: 1 }); // 一日加算
```

公式github
https://github.com/moment/luxon

## まとめ

| 順位 | ライブラリ | 理由 |
|:-: |:-: | :-: |
|1| date.fns | 型定義が充実し、デフォルトのdateに似ている|
|2| day.js| 軽量であり、全てのブラウザに対応している |
|3| Luxon.js | 処理が重いこと |
|4| moment.js | 現在は仕様が推奨されていないこと |

4つの候補から「date.fns」を使用することにします。
Excelにコピペができない場合はNULL文字を疑う

# 事象

次のようなテキストファイルがあるとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/38d2a738-5c5c-ccd8-9761-51162735cca8.png)

このテキストを全選択し、Excelにコピー&ペーストしたところ、途中までしかExcelにコピーされませんでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/4b1067ff-7acd-56bb-556d-7c0a7bd87922.png)

# 原因

原因はNULL文字です。Rubyを利用して、文字の中身をインスペクションしてみましょう。

```
$ cat input.txt | ruby -n -e 'p $_'
"ABC DEF\u0000GHI"
```

DEFとGHIの間にあるのは一見すると、単なる空白に見えますが、実際はNULL文字でした。そのため、ExcelはDEFで文字列が終了していると判定し、それ以降を切り捨ててしまったのです。

対応方法としてはいろいろ考えられますが、今回はNULL文字をコピペ可能な文字に置換することで対応しました。
未経験エンジニアの3ヶ月間の振り返り

今年1月から、新しい職場で未経験のエンジニアとして働き始めたので、その振り返り。
3ヶ月以上在籍しているような濃密な日々を送らせてもらったので、出会いに感謝。

その上で、実際に仕事を進めながら「これはやって良かった」と思う点と「今後改善したい」と思う点があるので、まとめる。また、自分のキャリアについても思うところがあったので、自分自身を見つめ直す意味でも書いていきたい。めっちゃポエミーになっちった。

## わいのこと

 
一応自分のプロフィールも書く。
- 新卒でシステム運用保守の会社に入社、運用保守を経験後にSaaSやRPAなどのセールス
- 前職は日本語教師&デザイナーとしてフリーランスで2年半働く（色々あった）
- プログラミングブートキャンプに参加し、スタートアップでエンジニア（イマココ）


## やって良かった（と思う）点

### 1. 主体的に動く、自分から情報を取りに行く
やって良かった第一はこれ。評価されているっぽいのも多分ここ。
基本はリモート勤務なので、どれだけ自分で情報を取りにいけるかが肝。

基本的には「質問する」＝「情報を取りに行く」だが、スタートアップで皆さん多忙すぎてカオスなので、意識していたのは、「相手の返信しやすさ（長くしすぎない）」こと。
そうするためには、自分の中で土台となる情報や知識を入れておいて、「ここまで考えて、ここは聞かないとわからないだろう」というポイントを見つけるように一応努めた。
ただ時間は掛かるので、組織文化によってはさっさと聞いてくれっていうのもあるかなと。
わいは新卒で入社した会社が「ここは聞かないとわからない」までを求める文化だったのと、slackの会話を観察（？）しているとそういう文化っぽかったので、そういう風に進めた。

あと、なんだかんだで「会う」っていうのが一番情報取れたなーと。
2月に大きなプロジェクトがあって、結構な裁量を持たせてもらい進めていたんだが、あまりにも情報が無さすぎて、一緒にプロジェクト進める担当者の人が出社するタイミングで会いに行った。そして、飲み会も開いてもらったので、そこでエンジニアチームと話した。
この実際に会ったことで、テキストでは想像できない様々な情報をキャッチアップできたし、めちゃくちゃリモートでコミュニケーションとりやすくなった。早い段階で会っておくは大事。リモートだと難しい場合もあるけども。

### 2. 「わからない」や問題は早めに開示する
仕事というのは信頼関係がとても大切だと思うんですが、この未経験エンジニアがつよつよエンジニアさんと信頼関係を築いていく上で重要だなと思っているのが、「わからないと言うこと」だと最近思っておるます。

ナレッジワークの麻野さんが「チームに問題はあっていい」って仰っていたが、問題を隠してもいつかは対応しなければならず、早めに対応すると大きな問題にならないことが多いので、「わからない」を早めに言う人は信頼できるのと思っておる。そこで怒ってくる人がいる職場はきっとこれから廃れていくので、気になくてOK！（笑）
https://youtu.be/bmHzQQCa_Xo?si=PVGY6Yiqp1uHhL8G

### 3. 失敗を怖がらずにやってみる
アーリーステージのスタートアップということもあり、基本的に試行錯誤中なことが多い。なのであんまり失敗が失敗にならない。行動しないのが一番の失敗。なので、「わからない点も多いがなんとか責任持ってやる」という姿勢で設計や実装を進めたのが結果として成果になった。成果というか、アウトプットができた段階かな。まだ成果と言えるものではないが。2にもつながる点。


## 反省点と今後の取り組み

### 1. 技術力の向上
なんといってもこれ。エンジニアである限りはまずこれ。コードもクリーンではないと思うし、パフォーマンスなど考えられることが少なすぎる。基本はフロントエンドだが、VueやNuxtにやっと慣れてきた段階なので、ちゃんと体系立てて学びたい。今なら本も読めると思うので、毎日10分は頑張ろう。「クリーンコードクックブック」というのを頑張って買ったので、少しずつ読むぞ。あとはQiitaで記事書こう。会議の時に技術の話をするが、やはり言語化が足りないと感じる。ドラフトを音声を通してAIでテキスト化してもらい、それを修正するのが今は良い感じ。

### 2. 優先度と重要度を考えて動く
アスタートアップということもあり、予定外のトラブルや急な依頼がポンポン降ってくる。目の前のことに対応するのが現時点の私に求められることだとは思うが、イエスマンになってはいけないと思うので、冷静に状況を見て言いにくいことも言う。そしてしっかり動いていく。「イシューからはじめよ」をバイブルにしたい。ていうか読書会したいぐらい。

## 気づいたこと（自分について）
### 1. 俯瞰して物事を考えがち
学生時代に社会学をやっていたこともあり、割と大きな単位で物事を考えるタイプだと気づく。それと同時に72時間ドキュメンタリーとかも好きで、ミクロに人がどんなことを考えるのかを想像するのも好き。これが私にとっては当たり前だったのだが、そうではないこともあるらしい。なので、事業を俯瞰して考えたり、その上で何をするのが組織にとって良いのか、社会課題を解決するのにつながるのかを一生考えられるのは割と強みかもしれないなと最近割と思う。ミッションや事業に共感するときに限るのだが。

### 2. デザイン経験が役に立っている
やっぱりデザインできるの良いのだなと。デザイナーいないので、デザイン作ったりもするんだが、良い反応をいただくことが多くてありがてえ。しかし、わいはビジュアルデザインの方をメインにやってきており、UI＆UXはやりながら勉強しているため、この辺は勉強したい。理論も頭に入れたい。色々中途半端にならないように注意と思いつつ、今の段階ではジェネラリストが必要とされている感があるので、なんでも吸収したい。

## おわりに
この3ヶ月は手探りで進んでいたが、諸先輩方や周囲のおかげで何とか乗り越えることができた。
今後も主体的に動きつつ、改善もしながら、事業成長に貢献できるよう頑張りたい。もちろん技術も伸ばしたいし、PM的なスキルも身につけたくて、やりたいことは山積みだが、そこが面白さでもある気がする。がんばるんば〜！
ExcelやPowerPointのオートコレクト機能をオフにする (Office365)

ExcelやPowerPoint(Office365)にはオートコレクトという機能があります。この機能はスペルミスを検出し自動で修正するものなのですが、邪魔になることもしばしば。そこで本記事では、オートコレクト機能をオフにする手順を示します。なおスクリーンショットはExcelで示しますが、PowerPointでもほぼ同じ手順です。

① ファイルタグを選択する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/79fdf2ac-3da8-7efc-71bd-c4c2374df4a8.png)

② その他 > オプション を選択する。

![スクリーンショット 2023-11-25 081856.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/e1386160-e0a2-f734-cc3e-acea2d673b1f.png)

③ 文章校正 > オートコレクトのオプション を押下する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/638e5fcf-55f1-747b-3902-0d0fccf2be47.png)

④ オートコレクトタブを選択し、朱枠のチェックを外した後、OKボタンを押下する (細かい設定は可能ですが、すべてのチェックを外しておくのが無難)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105859/d6b2453f-30f7-53f1-c1b3-2422045d238b.png)

__環境情報__

Microsoft® Excel® for Microsoft 365 MSO (バージョン 2410 ビルド 16.0.18129.20200) 64 ビット
Chrome複数ダウンロード許可

# 複数ダウンロード許可をSeleniumで行う

# 設定なし

```python
from selenium import webdriver

url = "https://www.python.org/"

driver = webdriver.Chrome()
driver.get(url)

# 以降要素を取得しダウンロード処理
```
この状態で継続してダウンロードを行うと
複数ダウンロードの許可/ブロックのアラートが表示され、
どちらか選択しないとダウンロードしなくなる。

![スクリーンショット 2025-02-08 075318.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3634951/9d126379-cdf6-a684-4ca4-76462345094d.png)


## Optionを追加する

```python
from selenium import webdriver

chrome_options = webdriver.ChromeOptions()

prefs = {'profile.default_content_setting_values.automatic_downloads': 1}  # 自動ダウンロードを有効化
chrome_options.add_experimental_option("prefs", prefs)
driver = webdriver.Chrome(options=chrome_options)

driver.get(url)
```
**1 : 許可**
**2 : 拒否**


# 参考サイト
https://stackoverflow.com/questions/68457042/how-to-allow-chrome-driver-to-download-multiple-files-selenium/68457100
Azure Cosmos DB アクセス専用Functionアーキテクチャ設計ガイド

2025年4月よりAzureを触りだしたので、思ったことをつらつらと。



## はじめに

Azure Functions を活用したアプリケーション開発において、Cosmos DBとの接続は頻繁に発生します。しかし、Function App が複数に分かれたり、Function数が増えると、Cosmos DBへの接続構成が複雑になり、Private EndpointやDNSの管理が煩雑になります。

そこで本記事では、**Cosmos DBアクセス専用のFunctionを1つに集約する設計アーキテクチャ**について、その利点・構成・考慮点を解説します。

---

## 構成の課題：FunctionごとにCosmos DBへ直接アクセスする場合

- 各Function Appごとに Cosmos DB への接続が発生
- **Private Endpoint（PE）をFunctionごとに構成しなければならない**
- Private DNSのリンク、NSG/UDR設定、コストもFunction数に比例して増加
- 管理・保守・トラブルシュートが煩雑化

---

## 解決策：Cosmos DBアクセス用の専用Functionを1つに集約！

### アーキテクチャ構成


```text
+-------------------+     HTTP/API     +-----------------------------+
| Function A        |---------------->|                             |
| Function B        |                 | Cosmosアクセス専用Function  |
| Function C        |---------------->| (PE + DNS構成済)            |
+-------------------+                 +--------------+--------------+
                                                    |
                                                    v
                                              [ Cosmos DB ]
```
### メリット

- **Private Endpointを最小限（1つ）にできる**
- データアクセスの責務が明確化し、**設計がシンプルになる**
- 他のFunctionからはHTTP/API通信で呼び出すだけなので、**Functionの追加・変更が容易**
- **セキュリティポリシーやNSGも集中管理可能**

---

## 実装上の考慮点

### 通信方式

- Functions間は **HTTPまたはManaged Identity経由の呼び出し**を推奨
- 必要に応じてFunction KeyやAPIMなどで認証制御

### スキーマ管理

- Cosmosアクセス専用Functionは **明確なAPI契約（JSONスキーマなど）**を持たせると運用がスムーズ

### ネーミングと設計方針

- `CosmosProxyFunctionApp`などの名前で明示
- `/api/cosmos/queryItem` や `/api/cosmos/upsertDocument` のようなREST設計で統一

### レイテンシ

- Functions間の通信は **同一リージョン＋バックボーン経由ならmsオーダー**で影響はほぼない

---

## 拡張性と保守性の向上

- **Function追加時にCosmos接続処理を実装し直さなくてよい**
- **Cosmos DBの構成変更（DB名・パーティションキー等）もProxy Functionのみ修正で済む**
- 将来的に **APIMやgRPC、Service Bus経由にリファクタリングしやすい**

---


## パフォーマンスとスケーリングの最適化

Azure Functions（特に従量課金型）の課題として知られる「コールドスタート」は、  
アプリケーションの応答性に大きく影響します。これを軽減する上でも、Cosmos DBアクセスを1本に集約する構成は効果的です。

### コールドスタートとは？
- Azure Functions は、一定時間アクセスがないとインスタンスを停止します。
- 停止状態から再起動する際に、数秒〜十数秒の遅延が発生します。

### なぜ集約構成でコールドスタートが起きにくくなるのか？

- 全てのリクエストが Cosmos DB 専用Function に集中するため、
- この Function は **常にトラフィックが流れる「水が流れる構造」** となり、
- **スケールインされにくく、ウォーム状態が維持されやすい**のです。

### 分散構成との比較：

| 構成 | コールドスタートの可能性 | 備考 |
|------|--------------------------|------|
| 各Functionが分散してDBに直接アクセス | 高い | 呼ばれないFunctionがコールドになる |
| Cosmos DBアクセスを1本に集約 | 低い | 常にリクエストが流れているためインスタンス維持されやすい |

> 結果として、**応答時間の安定性・パフォーマンス向上にもつながる構成**となります。

---


## まとめ

| 観点 | 集約型アーキテクチャのメリット |
|------|------------------------------|
| コスト | PEやDNS構成が最小限で済む |
| 運用 | Cosmosアクセスを1箇所で管理可能 |
| セキュリティ | NSGや認証制御が一元化できる |
| 拡張性 | 新規Function追加がスムーズ |

> Azure Functions が複数ある構成でも、Cosmos DBアクセスは専用Functionにまとめることで、セキュアかつスケーラブルなアーキテクチャが実現できます！

---

今はベストな整理構成を未来の自分にプレゼントする時代！  
設計の一手間が、開発効率と運用安定性を何倍にもしてくれるよ。
VDO.Ninja まずはこれだけで使ってみて！ (旧: OBS.Ninja)

# VDO.Ninjaとは

インストールもアプリも不要、ブラウザだけで映像や音声をやり取りできるツール。スマホからもいける！

送る方も受ける方も、URLひとつ送るだけ！

しかも遅延がDiscordのGoLiveよりも低遅延だという噂…

## 初回向け便利な使い方

最初はこの３つ！

### カメラとマイクを送信する

```
https://vdo.ninja?push=<id>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274492/6c752365-b8b3-4597-bb43-f31c8123a25f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274492/0256962f-67a8-4cac-8b9d-6340d909587f.png)

### 受信する

```
https://vdo.ninja?view=<id>
```

基本は開くだけでOKだけど、丸い再生ボタンが出るときは画面を1回クリックしたら見れます。

まだ送信されてなかったらグルグルマークが出ます。

受信側は、送信側が何を送信するにしても同じです

### 画面共有を送信する

```
https://vdo.ninja?push=<id>&ss
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274492/24cc0d71-c221-497f-aa47-3506bb245dca.png)


カメラとマイクを送信する方法でもできるけど、これにすると画面共有しかボタンが出てこないから楽

### IDとは？

パスワードみたいなもの

送信者と受信者で同じIDだと、つながる。

#### 1送信者→複数受信者 も可能

IDを同じにするだけ。

#### １つのPCから複数のIDで送受信することも可能

ブラウザタブやブラウザソースを複数用意し、それぞれに違うIDで開けば送受信を複数することも可能！


## これだけ覚えとけ！品質に関わるパラメーター

### 映像を高品質にする

送信側
`&s`をつける▼
`https://vdo.ninja?push=<id>&s`

受信側
`&vb=20000`をつける▼
`https://vdo.ninja?view=<id>&vb=20000`

### 音声を高品質にする

送信側
`&q`をつける▼
`https://vdo.ninja?push=<id>&q`

受信側
`&ab=320`をつける▼
`https://vdo.ninja?view=<id>&ab=320`

### 処理を軽量&高画質になりやすくする

受信側
`&codec=vp9`をつける▼
`https://vdo.ninja?view=<id>&codec=vp9`

## もっとパラメーターを知りたい！使いたい！

パラメーターはURLの後ろにつなげていけば、複数を同時に指定できます！

### 知りたい！

このページに対応している**全パラメータ**が載っています

[Complete List of Parameters in v26 - Ninja Docs](https://docs.vdo.ninja/advanced-settings/complete-list-of-parameters-in-v26)

トイレやお風呂に貼ってみんなで覚えよう！（嘘）

### 使いたい！

パラメーターはURLの後ろにつなげていけば、複数を同時に指定できる！
なんで？

#### URLパラメータ のしくみ

この記事の「パラメ-タ-（クエリ文字）」のところが詳しいです

https://qiita.com/mrshouuge/items/8eb61dfaddff744f69eb#%E3%83%91%E3%83%A9%E3%83%A1-%E3%82%BF-%E3%82%AF%E3%82%A8%E3%83%AA%E6%96%87%E5%AD%97

簡単に言うと、
```〇〇=△△```
の形で設定を、`&`でつなげてるって感じ
最初のURLとの境目を`?`で表しています。

## もっと使いたい！

RoomやDirector機能を使えばもっといろんなことができるけど、
そんなのはもっとツヨツヨになってからでいいのだ！

焦るな！

できることから始めろ！

https://castcraft.live/blog/211/

## まとめ

みんなもこれで毎日コラボ配信しようぜ！！！
Excelで飛び飛びのセルをコピペするＶＢＡコード

Excelで離れた飛び飛びのセルをコピペするVBAコード。
https://excel-windows.hateblo.jp/entry/excel-skip-cell-copy-paste

■値貼り付け
Sub CopyDiagonalCells()
    Dim cell As Range
    Dim baseRow As Long
    Dim baseCol As Long
    Dim pasteStart As Range

    Set pasteStart = Application.InputBox("貼り付け開始セルを選んでください", Type:=8)

    baseRow = Selection.Areas(1).Cells(1).Row
    baseCol = Selection.Areas(1).Cells(1).Column

    For Each cell In Selection
        pasteStart.Offset(cell.Row - baseRow, cell.Column - baseCol).Value = cell.Value
    Next cell

    MsgBox "位置関係を保って貼り付けました！"
End Sub

■すべて貼り付け
Sub CopyDiagonalCellsFullCopy()
    Dim cell As Range
    Dim baseRow As Long
    Dim baseCol As Long
    Dim pasteStart As Range
    Dim wsSource As Worksheet
    Dim wsDest As Worksheet

    On Error Resume Next
    Set pasteStart = Application.InputBox("貼り付け開始セルを選んでください", Type:=8)
    On Error GoTo 0
    If pasteStart Is Nothing Then Exit Sub

    Set wsSource = ActiveSheet
    Set wsDest = pasteStart.Worksheet

    baseRow = Selection.Areas(1).Cells(1).Row
    baseCol = Selection.Areas(1).Cells(1).Column

    For Each cell In Selection
        Dim rOffset As Long
        Dim cOffset As Long
        rOffset = cell.Row - baseRow
        cOffset = cell.Column - baseCol

        cell.Copy
        wsDest.Cells(pasteStart.Row + rOffset, pasteStart.Column + cOffset).PasteSpecial Paste:=xlPasteAllUsingSourceTheme
    Next cell

    Application.CutCopyMode = False
    MsgBox "値・書式・罫線などをすべて同じ形で貼り付けました！"
End Sub
Cursorに日記を読んでもらう

こんばんは、座禅いぬです。今さらアニメの「チ。」を見始めて、精神的にダメージを受けまくっております。<strong>自由に学べるって本当に素晴らしいな</strong>と思います。しかも今はYouTubeやZoom、SlackにDiscordと、無限に勉強出来てほんと楽園みたいな時代ですよね。

いつも参加している勉強会で<strong>Cursorをテキストエディタとしてタスク管理などに使っている</strong>方のLT（参考記事:[私のCursorAIの使い方](https://zenn.dev/calico923/articles/27708327fdc835)）を聞いて、僕も使ってみようと思い、むかーしにインストールだけして放置してたCursorを使い始めてみました。以前触ったときよりだいぶ使いやすくなっているなと感じました。そして、コーディング以外の用途に使うというところがすごく面白いなと思っています。

技術的な話とはまたちょっと違うのですが、自分が今試していることを書いておこうという忘備録です。

## 毎朝小論文を書く

小さいころからなぜか文章を書くのが好きで、毎朝小論文を書きます。人に見せるのも勇気がいるので、こっそり書いて誰にも見せないことがほとんどです（最近勇気を出し始めたわけです）。内容は

- 調べもの
- 自分の思考をまとめるため
- アイディアを捻出したい
- 考えていることを客観視したい
- 人に伝えたいことをわかりやすくまとめたい

このような感じだったりします。ライフワークというほど大したものではないですが、ずっと続けている習慣ですね。これをCursorでやってみたいなと。

### Cursorを使うと何がうれしいのか
Cursorで生成AIを用いるのは、別に文章を書かせたいわけではありません。というか、自分で書きたくて文章を書いてるので、本末転倒なわけです。むしろ<strong>読ませたい。</strong>

- <strong>書いた文章を客観的に評価</strong>してほしい
- <strong>過去の小論文を参照</strong>して調べてほしい
- 調べたりまとめたりしやすいように<strong>メタデータを付与</strong>してほしい
- アドバイスや、そこから展開できる<strong>発想のヒント</strong>が欲しい
- 本当に困ったときには生成AIの力を借りやすいよう、渡しやすい形式にしておきたい
- 将来的に自分の考え方や性質をAIに学習させられるような準備をしておきたい

人に見せるのは恥ずかしい内容でもAIなら安心！読んでもらえるってうれしいですよね。

## 具体的手法
まず、Cursorに対話形式でやりたいことを伝え、<strong>「要件定義にまとめてファイル生成して」</strong>と依頼します。生成された要件定義を書き直したり、修正依頼をして自分のやりたいことを煮詰めます。

次に、要件定義に基づいてテンプレートを作成してもらいます。

```
# 日次思考記録 - 2024-04-05

## 時間
開始時刻：
終了時刻：

## 論文形式選択
- [ ] 基本形式（序論・本論・結論）
- [ ] 研究論文形式（緒言・目的・材料と方法・結果・考察・結論）
- [ ] ビジネス提言形式（問題提起・解決策・効果検証）
- [ ] PPDAC形式（Problem・Plan・Data・Analysis・Conclusion）
- [ ] デザイン思考形式(共感・定義・概念化・プロトタイピング・評価)
- [ ] 水平思考形式(問題・現状・SCAMPER法・ブレインストーミング・アイディアの整理・結論)
- [ ] ディベート形式(論点・論拠・論証・結論/反論)
- [ ] 仮説思考形式(仮説・検証・結果・考察)
- [ ] 自由形式

# 本文

[ここから自由に記述開始]

---

## LLM分析用メタ情報

### キーワード
- [キーワード1]
- [キーワード2]
- ...

### 中心的な問い
- 主要な問い：
- サブクエスチョン：
  * 
  * 
  * 

### 前回からの進展
- 関連する過去の思考セッション：
- 前回からの発展点：
  * 
  * 
- 未解決の課題：
  * 思考の長期的な蓄積方法
  * 進捗の可視化手法
  * LLM分析結果の具体的活用方法

### 論理構造分析
- 形式：
- 構成：
  * 
  * 
  * 
- 強み：
  * 
  * 
- 弱み：
  * 
  * 
- 論理的整合性の評価（1-5）：
  * 前提の妥当性：
  * 論理展開の一貫性：
  * 結論の導出：

### 思考パターン
1. 
2. 

### 反論・対立視点
1. 
   - 根拠：
   - 考えられる反駁：
2. 
   - 根拠：
   - 考えられる反駁：

### 検出されたバイアス
1. 
   - 説明：
2. 
   - 説明：

### 重要な洞察
1. 
   - 重要度：
   - 理由：
2. 
   - 重要度：
   - 理由：

### 今後の方向性
- 
- 
- 

### 特定された核心的価値観
- 
- 
- 

### 次回への提案
1. 
2. 
3. 

### 外部レビュー
※ テーマと内容に基づき、最適なロールを自動選定

#### ロール選定理由
- 選定基準：
  * テーマ分類：
  * 主要論点：
  * 必要な専門性：

#### レビュー
レビュー1（ロール：[自動選定]）
本文章は～

レビュー2（ロール：[自動選定]）
本文章は～

レビュー3（ロール：[自動選定]）
本文章は～ 

```

Cursorに<strong>「今日の日記を書くよ～」というと、テンプレートに日付や前回の内容をあらかじめ入力してファイル作成してくれる</strong>ので、テーマに応じて文章の形式を選択し、記載します。だいたい2000字ぐらいの簡単なものが多いです。

さて、テンプレートの後半は文章を読んだCursorが内容をレビューしてくれます。文章を綺麗に書けるようになりたいので、ちょっと辛口レビューがいいと思い、文章の論理構造の妥当性や、批判的な意見・反論、文章のバイアスなどを客観的に評価してもらうことにしました。

ついでにうっかり、テーマに合わせてロールを設定して専門家のレビューをさせるようにしたのですが、<strong>これがとても厳しくて毎日泣きそうになる</strong>結果となりました。でも、朝1人で泣いていても誰にも見られないので大丈夫です。

## まとめ
以上、新しい取り組みとして<strong>Cursorに自分の書いた文章を「読んでもらう」</strong>ことで、より充実した日記ライフを送るための取り組みでした。しばらくこの形式で取り組んでみて、また発見やアップデートができれば面白いなと思います。

なお、このやり方を実行したところ、<strong>無料プランのチケットは一日で消滅した</strong>ため、有料プランへすぐに移行する羽目になりました。生成AIはお金がかかりますね。でも20ドルぐらいで毎日日記読んでもらえるんだから、全然やすいなと思います。
Setとsizeで単語数を取得！

Paizaの問題を解いてたら、「単語数をカウントせよ！」みたいな問題が出てきた。
これ、`Set`と`.size`を使えばめっちゃスッキリ解けるんだよね。


## <br>問題概要

スペース区切りの文字列を改行して出力。ただし、
	•	同じ単語は1回だけ出力
	•	その後、出現した単語の種類の数だけ 1 を出力

<br>入力例
```
red green blue blue green blue
```
出力例
```
red  
green  
blue  
1  
1  
1  
```
https://paiza.jp/works/mondai/c_rank_skillcheck_archive/word-count_05

## <br>初めのコード
```js
const rl = require('readline').createInterface({input: process.stdin});

rl.on('line', (input) => {
    const words = input.split(' ');
    const seen = new Set();

    words.forEach(word => {
        if (!seen.has(word)) {
            console.log(word);
            seen.add(word);
        }
    });

    for (let i = 0; i < seen.size; i++) {
        console.log(1);
    }

    rl.close();
});
```
## <br>他のコード例（改善？）
```js
const rl = require('readline').createInterface({ input: process.stdin });

rl.on('line', (input) => {
    const words = input.split(' ');
    const seen = new Set();
    const output = [];

    words.forEach(word => {
        if (!seen.has(word)) {
            output.push(word);
            seen.add(word);
        }
    });

    console.log(output.join("\n"));  
    console.log(Array.from(seen).map(() => 1).join("\n"));  

    rl.close();
});
```

### <br>解説

✅ `Set` は 重複を自動で排除 してくれる！
✅ `.size` を使えば ユニークな単語数を取得 できる！
✅ `Array.from(seen).map(() => 1).join("\n")` で 1 の出力を`size`もループもなしで実装！

### <br>まとめ
•	`Set` の特性を活かせば、重複をチェックする手間が減る！
	•	`.size` を使えば、要素数のカウントも楽勝！
	•	`map(() => 1)` のテクニックで、出力もシンプルに！


<br>[僕の失敗談と解決談！](https://paizabeginner.wordpress.com/2025/04/05/paiza%e3%81%a7%e5%9f%ba%e6%9c%ac%e3%83%9e%e3%82%b9%e3%82%bf%e3%83%bc%ef%bc%9aset%e3%81%a8size%e3%81%a7%e5%8d%98%e8%aa%9e%e6%95%b0%e3%82%92%e5%8f%96%e5%be%97%ef%bc%81/)
外国人エンジニアと一緒に働いたときの教訓

本日は外国人エンジニア（アジア系）と一緒に働いて感じたこと、学んだ教訓について書いていきます。

## ①細かい作業において日本人並みの丁寧さはないことが多い
はい、よく言われていることですね。
私は外国人エンジニアとちょくちょく一緒に働くことがあり、彼らの成果物をレビューすることがあります。
例えば、テストエビデンスを見ると結構適当で**テストエビデンスとしての要件を満たしていないようなもの**が上がってきます。
必要な情報が足りなかったり、そもそもテストの前提条件を満たしていないとかですね。これらの条件は事前に明文化されているはずのものなので、知らなかったという事はないはずなんですが、話を聞く限りあんまり細かく見てないようです。
あとは**開発規約とかそもそも見てない**とかもありました。

なので、彼らのレビューをする時はコードやエビデンスが要件、ルールを満たしているかどうかを普段よりもしっかり見るようにしています。

## ②不手際を見つけても怒らない、叱らない
最近は職場で怒ってはいけないのは誰が相手でも一緒だとは思いますが、①のようなケースが発生しても決して語気を強めないようにしています。彼らの文化では人前で怒るとか叱ることが**マジで地雷**ということがあるからです。
「Aさん、これこういうルールあるんだけど、知らなかった？うん、知らなかったよね～これわかりづらいよね～。でも申し訳ないんだけど、これこのままじゃレビュー通らないからもう一回やり直してね？」みたいな感じで進めます。キモは**決して怒らないけど、決して通さない**です。ルールを守らないと絶対に仕事が終わらないと分かれば彼らはちゃんとやってくれます。
ちなみに、同様の事象が何度も起きた時とうとう怒ってしまった同僚Bは、**Bさんこわい…もっと優しく…みたいな感じでエンジニアたちからクレーム出て、もっと上の人から怒られてました。** ~~それはそれでこわい~~

## ③なんやかんや異文化で面白い
外国人エンジニアと一緒に働くと文化、考え方の違いに結構驚かされます。
一緒に飯食ってだらだらしゃべってると面白いんです。ベトナムって結婚式に500~100人呼ぶらしいですよ？知ってました？私なんか妻と結婚した時、式どころかフォトウェディングさえやってないですから雲泥の差ですよ。
それにコーディングなんかも「これはすごい！」と褒めてしまうイケてるものを出してくることもあります。
それに日本語なんてわかりにくい言語をちゃんとビジネスで使えるレベルに仕上げてくるんですから大したものです。


## 外国人エンジニアともうまくやっていきましょうね
私の観測範囲ではありますが、最近外国人エンジニアと一緒に働くことは増えてきました。
日本人の労働人口はどんどん減ってるし、それにあわせてITは慢性的な人手不足がずっと続いているとかコスト面とかそういうあれやこれやがあるんだと思います。
日本人とは感覚や文化が違うこともあっていろいろ大変なこともありますが、うまくやって無事プロジェクトを成功させてみんなで幸せになりたいものですね。

余談
インド人の英語ってめちゃなまってて聞きづらくないですか？私のカタカナ英語もあんな感じで聞きづらいのかと思うとホント申し訳ない気分になります。
Webサイトの安定稼働を支えるモニタリング手法とは？ ～Ypali.netを活用した事例～


現代のビジネスやサービスでは、Webサイトの安定稼働が大きな鍵を握ります。ダウンタイムや速度低下が発生すると、ユーザー満足度の低下や機会損失に直結するため、迅速な障害検知と対策が求められます。ここでは、**Ypali.net**を活用したモニタリング手法や、可用性向上のポイントについて紹介します。

---

## なぜモニタリングが重要か
- **ユーザー体験の向上**  
  ページの読み込みが遅い、あるいはアクセス不能といった問題は、ユーザー離脱を招きます。モニタリングによりリアルタイムで問題を把握し、迅速に対処することで、満足度を維持できます。

- **信頼性・ブランドイメージの確立**  
  サービスが安定して稼働していることは、企業やプロジェクトの信頼性を高めます。継続的なモニタリングで障害を未然に防ぎ、ブランド価値を損なわないようにすることが大切です。

- **コスト削減**  
  問題を早期に発見できれば、大規模障害や二次被害を防ぐことが可能です。結果として、修復にかかるコストや機会損失を抑えられます。

---

## Ypali.netとは？
[Ypali.net](https://ypali.net) は、Webサイトの可用性やパフォーマンスを継続的に監視し、**障害発生をリアルタイムに検知**して通知してくれるサービスです。加えて、ユーザーからの苦情やフィードバックも一元管理できるため、問題点を総合的に把握・分析できます。

### 特徴
1. **リアルタイム監視**  
   サイトのダウンタイムや速度低下を素早く把握。  
2. **詳細なアナリティクス**  
   レスポンスタイムやエラーログなどを可視化し、原因究明をサポート。  
3. **ユーザーフィードバックの収集**  
   障害報告や苦情を集約し、問題の優先度を見極めやすく。  
4. **通知機能**  
   メールやSNS、チャットツールなどでアラートを受け取ることが可能。

---

## モニタリング導入の流れ
1. **Ypali.netに登録**  
   アカウントを作成し、監視したいドメインやURLを追加します。  
2. **監視間隔や通知設定をカスタマイズ**  
   監視頻度やアラートの送信先を自社の運用体制に合わせて設定。  
3. **ダッシュボードで状況を確認**  
   リアルタイムのステータスや履歴をチェックし、問題を早期に発見。  
4. **レポートの活用**  
   定期レポートを参考にサイトのパフォーマンスを分析し、改善施策を検討。

---

## 可用性向上のためのヒント
- **冗長化構成**  
  サーバーやネットワークを冗長化して、単一障害点（Single Point of Failure）を減らしましょう。  
- **キャッシュの活用**  
  CDNやブラウザキャッシュを適切に設定することで、レスポンスを高速化できます。  
- **定期的なテスト**  
  ロードテストや脆弱性スキャンを実施し、潜在的な問題を洗い出します。  
- **ユーザーフィードバックの収集**  
  監視ツールだけでなく、実際のユーザーの声も重要です。障害検知には表れない使い勝手の問題が見つかることもあります。

---

## まとめ
サイトの安定稼働はユーザー満足度やビジネスの成果に直結する重要な要素です。**Ypali.net**のようなサービスを活用して、リアルタイムで問題を発見・解決し、可用性を高めることが現代のWeb運営には欠かせません。定期的なモニタリングと継続的な改善を行うことで、信頼性の高いオンラインサービスを提供し続けましょう。

もし何か質問や追加情報が必要でしたら、コメント欄でお気軽にお声がけください！
AtCoderをPythonで取り組んだ振り返り(ABC400 A,B)

どうもこんにちは！

今週もAtCoderのコンテストに参加できたので、記録がてら振り返ります。
今回はBまで完答。CはよくわからずDの方が解けるかもと思い取り組んだんですが解答できず。

問題

問題は以下のリンクから。取り組めたA,Bを振り返ります。

https://atcoder.jp/contests/abc400/tasks

# A - ABC400 Party -
ABC400回記念？ということで、400人を与えられた正の整数Aを使ってA行B列に並べることができるかを判定する問題。シンプルに与えられた正の整数で400を割れるかを判定すればよいですね。
~~~Python
n = int(input())
print(400 // n if 400 % n == 0 else -1)
~~~

# B - Sum of Geometric Series -
与えられた正の整数n,mを使って、$X = \sum_{i=0}^{m} n^i$を計算し、Xが$10^9$以下ならXを、超えるならinfを出力するという問題。
シンプルに数列を足し合わせて、結果にあわせて出力を変えるとしました。
~~~Python
n,m = map(int,input().split())
ans = 0
for i in range(m+1):
    ans += n ** i
print("inf" if ans > 10 ** 9 else ans)
~~~

# C - 2^a b^2 -
1以上与えられる正の整数n以下の整数のうち、正の整数の組(a,b)を使って$X = 2^a * 2^b$とできる整数の数を答える問題。
解法が何も思いつかずパスしたんですが、例えば3の2乗かつ2の乗数、次は5の2乗かつ2の乗数というように、2乗とする数を増やしながら数字を探していく方向なら計算量も少なく検索できたんでしょうか。

# D - Takahashi the Wall Breaker -
縦がhマス、横がwマスのグリッドで、中身は道か壁となっています。与えられるスタート座標からゴール座標に行くにあたって、壁を最小で何回壊せば到達できるかという問題。壁を壊す場合は上下左右のいずれかの方向で、最大2マスまで破壊可能という条件です。
コンテスト中に考えたのは、以下の手順。
　・スタート位置から到達可能な座標を幅優先探索で取得する。
　・ゴール座標から見て、到達可能な座標のうちもっとも近い位置を取得して、壁を壊す回数を算出する。
で、実際書いたコードが以下ですがTLEとなるケースがあり完答できていません。また、冷静に考えるとこの手順はスタートとゴールをつなぐ道が壁で途切れているだけのケースを考えられていません。道を途切れさせている壁を1回壊せば到達できる場合でも、その壁の位置がゴールから遠いほど複数回壊す結果になるはず、というわけです。

<details><summary>長いし間違っているので折りたたみ</summary>

~~~Python
from collections import deque

h,w = map(int,input().split())
grid = [list(input()) for _ in range(h)]
sy,sx,gy,gx = map(int,input().split())

q = deque()
q.append((sy-1,sx-1))
reach = [[-1]*w for _ in range(h)]
reach[sy-1][sx-1] = 0
while q:
    ny,nx = q.popleft()
    for dy,dx in ((-1,0),(1,0),(0,-1),(0,1)):
        if (0 <= ny+dy < h and 0 <= nx+dx < w):
            if grid[ny+dy][nx+dx] != "#" and reach[ny+dy][nx+dx] == -1:
                grid[ny+dy][nx+dx] = "*"
                reach[ny+dy][nx+dx] = reach[ny][nx] + 1
                q.append((ny+dy,nx+dx))

if reach[gy-1][gx-1] >= 0:
    print(0)
else:
    ans = 1
    s = False
    q  = deque()
    q.append((gy-1,gx-1))
    while True:
        y,x = q.popleft()
        for dy,dx in ( (-1,0), (-2,0), (2,0), (1,0), (0,-1), (0,-2), (0,1), (0,2)):
            if (0 <= y+dy < h and 0 <= x+dx < w):
                if reach[y+dy][x+dx] != -1:
                    s = True
                    break
                else:
                    q.append((y+dy,x+dx))
        if s == True:
            break
        
    print(ans)
~~~
</details>

# おわりに
解説見て復習して次に備えます。

ではでは。
2分でなれるプロンプトPythonエンジニアのはじめかた

使うプロンプト

```text
「足し算と引き算」を実行するPythonコードを書いてください。
以下の内容を含めた用件定義としてまとめてください。

**用件定義：**

1. **必要なライブラリのインストール命令を含むこと**
   - 必要なライブラリを最初にインストールする命令をコードに追加すること。

2. **代入する数値は一箇所にまとめること**
   - 数値の設定は一箇所にまとめ、変数に代入して動的に使えるようにすること。

3. **前置き部分は省略すること**
   - プログラムの説明や前置きは省略し、すぐにコードが記載される形式にすること。

4. **コメントの記載方法**
   - コード内には日本語と英語の両方のコメントを記載すること。
   - 動作原理の説明を詳細に行い、理解しやすく記述すること。

5. **matplotlib使用部分の英語での記述**
   - matplotlibを使用する部分では、グラフのタイトル、ラベル、凡例などをすべて英語で記述すること。

6. **プログラムの基本情報**
   - プログラム名、作成日、概要、使用方法を以下のように記載すること：


# Program Name: coffee_shop_sales.py

# Creation Date: 20250111
# Overview: A program to analyze coffee shop sales data and generate monthly sales reports
# Usage: To run the program, use the command `python coffee_shop_sales.py` in the terminal
7. **プログラムのコメントは日本語英語で詳しく記載**
  
以上の内容を含んだPythonコードを1つにまとめ、提供してください。

```

生成AIに入力

![IMG_8993.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4043781/3bdf6c0e-78f6-4d73-b680-dedfd7b4394b.jpeg)

![IMG_8994.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4043781/47159873-7685-4b7e-b5e4-e56f8b18f80a.jpeg)


出てきた出力コードをGoogleアカウントでログインしたGoogle Colabに貼り付けて実行。

https://colab.research.google.com/?hl=ja#scrollTo=0tJpu4mj1g4y

![IMG_8996.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4043781/daed1679-143c-4011-af1a-de69d10721c0.jpeg)


![IMG_8995.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/4043781/adc4a0ae-42b7-40ce-9c87-d62d90521e8e.jpeg)

分からないことは生成AIに聞いて

参考記事

https://qiita.com/skillup_ai/items/27676779e269f333a845

https://qiita.com/sekappy_official/items/e70318845b06c68d4799

https://www.google.com/search?q=Python+YouTube+%E3%81%8A%E3%81%99%E3%81%99%E3%82%81&sca_esv=342c1fe1167455aa&sxsrf=AHTn8zpX0jz6vOZyBTHswIk3Cj5SWynZQA%3A1744104717832&ei=De30Z5zCMqng2roP__2v6QI&oq=Python%E3%81%8A%E3%81%99%E3%81%99%E3%82%81%E3%82%86%E3%83%BC%E3%81%A1%E3%82%85%E3%81%B0&gs_lp=Egxnd3Mtd2l6LXNlcnAiIVB5dGhvbuOBiuOBmeOBmeOCgeOChuODvOOBoeOCheOBsCoCCAAyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEcyChAAGLADGNYEGEdIxglQAFgAcAF4AJABAJgBd6ABd6oBAzAuMbgBAcgBAJgCAaACG5gDAIgGAZAGCpIHATGgB7oGsgcAuAcA&sclient=gws-wiz-serp
git rebase は pull とは違いますか

# 🎲はじめに
そろそろ `rebase` が美味しい季節になってきましたね

分散型ヴァージョン管理システムを破壊しないように、`rebase` のことを把握して `コミットID` を意識していることをアピールするチャンス到来

基本gitコマンドはこちらの記事で確認してほしい

https://qiita.com/takekota/items/1bf43d4488efe5fd128d

# 🎬プロローグ
作業してたらmainブランチに知らないコミットができてた
```mermaid
graph LR
  subgraph main
    main01 --- main02
  end

  main01 --branch--> my001

  subgraph feature/my作業
    my001 --- my002
  end
```

# 📥pullの場合
リモートで merge branch してもいいけど、
コンフリクトの可能性あるしローカルで merge する手順。

## 1. merge_commitを作る
どっち向きにmergeしても結果は同じ
```mermaid
graph LR
  subgraph main
    main01 --- main02
  end

  main01 --branch--> my001

  subgraph feature/my作業
    my001 --- my002 --- merge_commit
  end

  main02 --pull--> merge_commit
```
```sh
# リモートmainブランチから、作業ブランチにpullする
git switch feature/my作業
git pull origin main
```
または
```sh
# ローカルのmainブランチを最新にする
git switch main
git pull origin main
# git pull origin main:main 上記2行を1行にしたもの

# ローカルmainブランチから、作業ブランチにmergeする
git switch feature/my作業
git merge main
```

## 2. リモートにpushする
```mermaid
graph
  subgraph main
    main01 --- main02 --- merge_commit
  end
```
```sh
# リモートmainブランチにpushする
git switch feature/my作業
git push origin main
```

## 📝説明
* `pull` = `fetch` + `merge`
* `fetch` : 最新の取得
* `merge` : 合併

**pullを使うと、マージコミットが作成される**
* メリット：変更が明確になる
* デメリット：履歴が複雑になる

# 🔧rebaseの場合
## 1. 作業ブランチのコミットIDを変更する
```mermaid
graph LR
  subgraph main
    main01 --- main02
  end

  main01 -.branch.-> my001

  subgraph feature/my作業
    my001 -.- my002
    my001' --- my002'
  end

  main02 --rebase--> my001'

style my001 stroke-dasharray: 5 5
style my002 stroke-dasharray: 5 5
```

```sh
# ローカルのmainブランチを最新にする
git switch main
git pull origin main

# ローカルmainブランチから、作業ブランチにrebaseする
git switch feature/my作業
git rebase main
```

## 2. リモートにpushする
```mermaid
graph
  subgraph main
    direction LR
    main01 --- main02 --- my001' --- my002'
  end
```
```sh
# リモートmainブランチにpushする
git switch feature/my作業
git push origin main
```

## 📝説明
mainの最新の取得してその先頭にリベース（移動）する
**コミットIDのみ変わる**

マージコミットが作成されない
* メリット：履歴が線形で理解しやすい
* デメリット：履歴が書き換えられるため、他の人とコンフリクトするかも

※すでにプッシュしているコミットを改変すると大変カオスなことになるので、 絶対に使用しないでください

# 🛠️interactive rebase
リベースの過程で各コミットを手動で変更できるモード
* **squash** : 複数のコミットを1つにまとめる
* **edit** : コミットメッセージや内容の変更
* **pick** : コミットの順序変更
* **drop** : 不要なコミットの削除

# 🎯選び方
プロジェクトのニーズ、チームの運用方針、目的で使い分ける
コミット履歴を意識するなら `rebase`

# 🔧 git rebase でコンフリクトが起きたときの解消手順
```sh
# 競合しているファイルを確認する
git status

# 競合を手動で解消する（対象のファイルをエディタで開いて、コンフリクトを修正）

git add <ファイル名>
git rebase --continue
```

❌ リベースをやめたいとき
```sh
git rebase --abort
```

リモートに push 済みのブランチを rebase した場合、履歴が書き換わるため通常の `git push` はできない
代わりに「強制 push（`git push --force-with-lease`）」が必要
ABC400振り返り


前回の振り返り

https://qiita.com/comet725/items/4becd20c8686ea137b93


今日はABC開催日だったので参加結果を振り返る

https://atcoder.jp/contests/abc400

今週はのA,Bの2完(0ペナ)

# A

割り切れるかどうかだけ分岐して
割り算

## ソースコード

```python:main.py
from bisect import bisect_left, bisect_right, insort_left, insort_right
from collections import defaultdict, Counter, deque
from functools import reduce, lru_cache
from itertools import product, accumulate, groupby, combinations
import sys
import os
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
IS_LOCAL = int(os.getenv("ATCODER", "0"))==0
err = (lambda *args, **kwargs: print(*args, **kwargs, file=sys.stderr)) if IS_LOCAL else (lambda *args, **kwargs: None)

def main():
    A = rI()
    ans = 400//A if 400%A==0 else -1
    print(ans)
    
if __name__ == '__main__':
    main()

```

# B

普通に総和して
$10^9$超えるかどうかで分岐するだけ

## ソースコード

```python:main.py
from bisect import bisect_left, bisect_right, insort_left, insort_right
from collections import defaultdict, Counter, deque
from functools import reduce, lru_cache
from itertools import product, accumulate, groupby, combinations
import sys
import os
def rI(): return int(sys.stdin.readline().rstrip())
def rLI(): return list(map(int,sys.stdin.readline().rstrip().split()))
def rI1(): return (int(sys.stdin.readline().rstrip())-1)
def rLI1(): return list(map(lambda a:int(a)-1,sys.stdin.readline().rstrip().split()))
def rS(): return sys.stdin.readline().rstrip()
def rLS(): return list(sys.stdin.readline().rstrip().split())
IS_LOCAL = int(os.getenv("ATCODER", "0"))==0
err = (lambda *args, **kwargs: print(*args, **kwargs, file=sys.stderr)) if IS_LOCAL else (lambda *args, **kwargs: None)

def main():
    N, M = rLI()
    X = sum(N ** i for i in range(M+1))
    ans = X if X <= 10**9 else "inf"
    print(ans)
    
if __name__ == '__main__':
    main()

```

# C

小数点の管理ができなくて爆散

# D

有向グラフ作ってBFSはしんどいて…

# E

エラトステネスの篩を使うところまでは見立てることはできたが
全列挙できる発想は出なかった。

# F

DP使いそうと思ったけど
漸化式わからん

# G

これもDP使いそうと思ったけど
Alien DP ってなんですかそれ

# 感想

記念すべき400回目だし久々にratedしたら無事に冷えたので辛い
でもこの辛さから逃げ続けると余計やりづらくなるんですけどねｌ…
ABC400をPythonで（A～E）

AtCoder Beginner Contest 400の解答等の速報的まとめ

https://atcoder.jp/contests/abc400



# A問題
https://atcoder.jp/contests/abc400/tasks/abc400_a

400で割り切れたらその商を、そうでなければ-1を出力する
```python:A
a=int(input())
print(-1 if 400%a else 400//a)
```
# B問題
https://atcoder.jp/contests/abc400/tasks/abc400_b

答えが$10^9$を超えるまで足す
```python:B
n, m = map(int, input().split())

ans = 0
for i in range(m + 1):
    ans += n ** i
    if ans > 10 ** 9:
        exit(print("inf"))

print(ans)
```
# C問題
https://atcoder.jp/contests/abc400/tasks/abc400_c

$b$に偶数が入らないものとして計算する。
```python:C
from math import isqrt

n = int(input())

ans = 0
for a in range(1, 60):
    b = isqrt(n // (2 ** a))
    ans += (b + 1) // 2

print(ans)
```
# D問題
https://atcoder.jp/contests/abc400/tasks/abc400_d

ふつうのbfsのように探索し、壁があったらそのマスと隣のマスをコスト+1で探索していく
```python:D
from collections import deque

h, w = map(int, input().split())
s = [input() for _ in range(h)]
A, B, C, D = map(lambda x:int(x) - 1, input().split())

INF = float("inf")
cnt = [[INF] * w for _ in range(h)]
q = deque()
q.append([0, A, B])
cnt[A][B] = 0
while q:
    c, x, y = q.popleft()
    if cnt[x][y] < c or cnt[C][D] <= c:
        continue
    for arr_i, arr_j in [[1, 0], [-1, 0], [0, 1], [0, -1]]:
        i, j = x + arr_i, y + arr_j
        if 0 <= i < h and 0 <= j < w:
            if s[i][j] == "#":
                if c + 1 < cnt[i][j]:
                    cnt[i][j] = c + 1
                    q.append([c + 1, i, j])
                if 0 <= i + arr_i < h and 0 <= j + arr_j < w and c + 1 < cnt[i + arr_i][j + arr_j]:
                    cnt[i + arr_i][j + arr_j] = c + 1
                    q.append([c + 1, i + arr_i, j + arr_j])
            else:
                if c < cnt[i][j]:
                    cnt[i][j] = c
                    q.appendleft([c, i, j])

print(cnt[C][D])
```
# E問題
https://atcoder.jp/contests/abc400/tasks/abc400_e

1. 素数の偶数乗で$10^{12}$以下のものをすべて求め、ソートする
1. 同じ素数を用いていない組み合わせかつ積が$10^{12}$以下のものを書き出してソートする
1. 各クエリの$A$以下で最大の数をbisectで出力する
```python:E
from bisect import bisect

def get_prime(limit):
    primes = [False] + [True] * limit
    primes[1] = False
    i = 2
    while i * i <= limit:
        if primes[i]:
            for j in range(i * i, limit + 1, i):
                primes[j] = False

        i += 1

    return [i for i in range(limit + 1) if primes[i]]


prime = get_prime(10 ** 6)
maxi = 10 ** 12
lst_i = list()
for p in prime:
    p_i = p ** 2
    while p_i <= maxi:
        lst_i.append([p_i, p])
        p_i *= p ** 2

lst_i.sort()
lst = set()
for i in range(len(lst_i)):
    for j in range(i):
        if lst_i[i][0] * lst_i[j][0] <= maxi:
            if lst_i[i][1] != lst_i[j][1]:
                lst.add(lst_i[i][0] * lst_i[j][0])
        else:
            break

lst = sorted(lst)

for _ in range(int(input())):
    print(lst[bisect(lst, int(input())) - 1])
```