OmniAICreator/Qiita-1.07M huggingface dataset:
【技術書】最近読んでよかった本まとめ

## はじめに
エンジニア歴1年目の頃に[「新人エンジニアの自分がおすすめする技術書ランキング2022春」](https://qiita.com/Yporon/items/dcb382284fc0f00bb12a)という記事を投稿したのですが、エンジニア歴も4年目に入ったということで、改めて最近読んで良かった本を紹介しようと思います。
前回の記事とは違い、ランキングづけはせずにビジネス紹介しようと思います。
ビビッとくるものがあればぜひ手に取ってみてください。

なお今回は紹介しませんが、いまだに1番読んでよかったと思っている技術書は[オブジェクト指向設計実践ガイド](https://www.amazon.co.jp/dp/B01L8SEVYI)です。最強です。
# [プロダクトマネージャーのしごと第二版](https://www.amazon.co.jp/%E3%83%97%E3%83%AD%E3%83%80%E3%82%AF%E3%83%88%E3%83%9E%E3%83%8D%E3%83%BC%E3%82%B8%E3%83%A3%E3%83%BC%E3%81%AE%E3%81%97%E3%81%94%E3%81%A8-%E7%AC%AC2%E7%89%88-%E2%80%951%E6%97%A5%E7%9B%AE%E3%81%8B%E3%82%89%E4%BD%BF%E3%81%88%E3%82%8B%E5%AE%9F%E8%B7%B5%E3%82%AC%E3%82%A4%E3%83%89-Matt-LeMay/dp/4814400438)

![](https://m.media-amazon.com/images/I/71oQeClrzgL._SY522_.jpg)
### 感想
- 仕事でプロダクトマネージャーっぽい動きはするけれど、実際に何したら良くて何をする人がPMなのかさっぱりわからんってなってた時に買いました(同じ状況の人がもしいればおすすめです)
- PMの仕事の輪郭は多少見えるようになったと思います。有り体な言い方をするのであればPMへの解像度が上がりました
- PMに求められるCOREスキルが言語化されていてよかったです
- 少なくともあらゆるパターンに対応するベストプラクティスはプロダクトマネジメントにおいてないということが理解できました
- ユーザーの現実に生きること、そして何を作らないかを判断できる戦略の重要性が理解できました


# [科学的根拠に基づく最高の勉強法](https://www.amazon.co.jp/%E7%A7%91%E5%AD%A6%E7%9A%84%E6%A0%B9%E6%8B%A0%E3%81%AB%E5%9F%BA%E3%81%A5%E3%81%8F%E6%9C%80%E9%AB%98%E3%81%AE%E5%8B%89%E5%BC%B7%E6%B3%95-%E5%AE%89%E5%B7%9D-%E5%BA%B7%E4%BB%8B/dp/4046067233)
![](https://m.media-amazon.com/images/I/71CGY6yA5AL._SY522_.jpg)
### 感想
- [世界一流エンジニアの思考法](https://www.amazon.co.jp/%E4%B8%96%E7%95%8C%E4%B8%80%E6%B5%81%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%AE%E6%80%9D%E8%80%83%E6%B3%95-%E7%89%9B%E5%B0%BE-%E5%89%9B/dp/4163917683)の著者である牛尾さんがTwitterで紹介されていて買いました
- タイトル通りですが、科学的に効果が高い勉強法を学べるのがよかったです。自分は科学的根拠って言葉に弱いということがわかりました
- 本を使ってその勉強法がいかに効力の高い勉強法かを体験できるのもよかったです
- 自分は割と多読で勉強するタイプだったのですが、科学的にみて効果の高い勉強法とは言えないと知り衝撃を受けました
- いかに脳に負荷をかけるかが勉強として大事であり、アクティブリコールが勉強法として強いということを学びました
- 実際にそれ以降の勉強法に自分は活かせてるので、実践しやすかった点も良かったです。思い込みもあると思いますが、アクティブリコールは記憶に定着してる感がすごいです
- 生きる限り学びが終わることはないので、こういうことを簡単にでも頭に入れておくと今後の知識の定着や吸収力に差が出るだろうなという気持ち

# [Clean Architecture 達人に学ぶソフトウェアの構造と設計](https://www.amazon.co.jp/Clean-Architecture-%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E3%81%AE%E6%A7%8B%E9%80%A0%E3%81%A8%E8%A8%AD%E8%A8%88-%E3%82%A2%E3%82%B9%E3%82%AD%E3%83%BC%E3%83%89%E3%83%AF%E3%83%B3%E3%82%B4-%EF%BC%B2%EF%BD%8F%EF%BD%82%EF%BD%85%EF%BD%92%EF%BD%94-%EF%BC%A3%EF%BC%8E%EF%BC%AD%EF%BD%81%EF%BD%92%EF%BD%94%EF%BD%89%EF%BD%8E-ebook/dp/B07FSBHS2V)
![](https://m.media-amazon.com/images/I/81Zl28yzWCL._SY522_.jpg)
### 感想
- 業務でクリーンアーキテクチャについて触る機会ができたので買いました
- アーキテクチャそもそもの目的について言語化されていたのが良かったです
- アーキテクチャの目的は、プログラムの振る舞いを安定させることではなく、開発・変更・保守・運用といったプログラムのライフサイクルを安定させることであるという話と、**ソフトウェアの価値には、「振る舞い」「構造」の2種類があり、より価値が高いのは「構造」である**、「構造」がシステムをソフトに、つまり柔軟に変更可能にするのである。という話が刺さりました
- 開発速度を取るために「振る舞い」を優先し「構造」を犠牲にしてきた経験があるので、反省です
- 設計思想や原則、アーキテクチャについて網羅的に学べるのが良かったです

## 終わりに
ここまで読んでいただきありがとうございました。今回は簡単に紹介しましたが、それぞれの本で学びになったことがたくさんあるので、いつか一冊一冊について詳細なレビューをQiitaで書きたいなと思っています。
【Flutter】UXの向上に向けて知っておいたら得すること

# 初めに
同期処理でプログラムが実行されるFlutterでは、非同期処理やUIのフレーム管理が非常に難しいし、UXを向上させるポイントにもなってきます。
そこで、今回はFuture.microtaskとWidgetsBinding.instance.addPostFrameCallbackの違いについて説明していきます。
これらのメソッドを適切に使用することで、より効率的で応答性の高いアプリケーションを構築できます。
本記事では、これらのメソッドの詳細な解説と、その使用例について説明します。

# Future.microtask

1. Future.microtaskとは？
Future.microtaskは、すぐに実行するべきタスクをスケジュールするためのメソッドです。Dartのイベントループ内で最も高い優先度を持つため、できるだけ早く実行されます。これは、非同期処理の中で短時間で完了するタスクを実行するのに適しています。

2. 基本的な使い方
Future.microtaskは、以下のように使用されます。

```dart
Future.microtask(() {
  // ここに実行するタスクを記述
  print('This is a microtask');
});
```
3. 実行タイミング
Future.microtaskでスケジュールされたタスクは、現在のタスクが完了した後、すぐに実行されます。これにより、緊急のタスクを迅速に処理することができます。

4. 使用例
例えば、UIスレッドをブロックせずに迅速にデータを処理する場合に使用できます。

```dart
void main() {
  Future.microtask(() {
    print('Microtask executed');
  });

  print('Main task executed');
}

// 出力:
// Main task executed
// Microtask executed
```

上記の例では、Main task executedが最初に出力され、その後にMicrotask executedが出力されます。これは、Future.microtaskが現在のタスクの完了後に実行されるためです。

# WidgetsBinding.instance.addPostFrameCallback

1. addPostFrameCallbackとは？
WidgetsBinding.instance.addPostFrameCallbackは、Flutterのウィジェットツリーが描画された後に特定のコールバックを実行するためのメソッドです。これにより、ビルドプロセスが完了し、画面に表示された後に実行される処理をスケジュールできます。

2. 基本的な使い方
addPostFrameCallbackは、以下のように使用されます。

```dart
WidgetsBinding.instance.addPostFrameCallback((_) {
  // ここに実行するタスクを記述
  print('This is a post frame callback');
});
```

3. 実行タイミング
このコールバックは、フレームの描画が完了した後に実行されます。そのため、ビルドコンテキストが完全にセットアップされた後に行いたい処理に適しています。

4. 使用例
例えば、画面にウィジェットが描画された後にアニメーションを開始する場合に使用できます。

```dart
class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addPostFrameCallback((_) {
      // ここに初期化処理を記述
      print('Widget tree has been rendered');
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Post Frame Callback Example'),
      ),
      body: Center(
        child: Text('Hello, World!'),
      ),
    );
  }
}
```

この例では、ウィジェットツリーが描画された後にWidget tree has been renderedが出力されます。これにより、ビルド完了後の初期化処理を確実に行うことができます。

# Future.microtaskとaddPostFrameCallbackの違いと使い分け

1. 実行タイミングの違い
Future.microtaskは、現在のタスクが完了した直後に実行されます。これにより、非常に高い優先度でタスクを処理できます。
WidgetsBinding.instance.addPostFrameCallbackは、フレームの描画が完了した後に実行されます。これにより、ウィジェットツリーが完全にセットアップされた後の処理が可能です。
2. 使い分け

```Future.microtask```:

短時間で完了するタスクを迅速に実行する必要がある場合。
UIスレッドをブロックせずにデータ処理を行いたい場合。

```WidgetsBinding.instance.addPostFrameCallback```:

ビルドプロセスが完了し、画面が描画された後に行いたい処理がある場合。
ウィジェットツリーがセットアップされた後に初期化処理を行いたい場合。

# まとめ
Future.microtaskとWidgetsBinding.instance.addPostFrameCallbackは、Flutterにおいて非同期処理やUIのフレーム管理を効率的に行うための強力なツールです。
これらを適切に使い分けることで、アプリケーションのパフォーマンスやユーザー体験を向上させることができます。各メソッドの特性と使用例を理解し、適切な状況で活用してください！
【初心者面接官必見】候補者の魅力を引き出す面接術

# 想定読者
この記事は、社内での面接経験が浅く、面接が苦手だと感じている方々を対象にしています。全てをそのまま実践する必要はありませんので、役立つと思われる部分を取り入れていただければと思います。

# はじめに
こんにちは、HRBrainの開発組織立ち上げに携わってきた川田です。
約6年半前、私は採用活動や面接の経験がほとんどない状態からスタートしました。他の人や書籍から学び、実践を重ねることで、より再現性の高い面接を実施できるようになりました。この知識を共有するために、この記事を書くことにしました。
面接の大前提としては、優秀かどうかを判断するのではなく、候補者が現在の会社の環境に合っているかどうかを見極めることが重要です。

# 構造
継続的に成果を出す人にはどのような特徴があるのでしょうか。この点について構造的に考えてみましょう。継続的な成果を出すためには、適切な振る舞いが求められます。成果を出すための振る舞いをするためには、適切に思考し状況を捉える必要があります。

思考 -> 行動 -> 成果

人は、「状況をどのように捉えるか」という思考のクセと、「ある状況でどのように振る舞うか」という行動のクセの2種類に分けることができます。

## 思考のクセ
思考のクセについては、「[**こころの資本**](https://amzn.asia/d/ey9wnQH)」という書籍で説明されている心理的資本を用いて理解できます。心理的資本には以下の4つの要素があります：

1. Hope（希望）
2. Efficacy（自己効力感）
3. Resilience（回復力/弾性）
4. Optimism（楽観性）

これらはHEROとも呼ばれています。これらの要素が強いほど、どんな逆境でも前向きに挑戦する力があります。面接では、これらの要素が現時点でどの程度備わっているかを見極めることが重要です。

## 行動のクセ
行動のクセについては、「[**人を選ぶ技術**](https://amzn.asia/d/eTHisQE)」という書籍で紹介されている「ポテンシャルモデル」を用いて説明します。これには以下の4つの特性が含まれます：

1. 好奇心
2. 洞察力
3. 共鳴力
4. 胆力

これらが強い人は、大きな可能性と成長の余地を持っています。

# 質問の切り口
考え方や意見は装飾が可能ですが、実際に行った振る舞いは真実性が要求されます。過去の振る舞いは、具体的な話を深堀することでその真実性をより確かめることができます。また、振る舞いには再現性もあります。
そのため、過去の振る舞いに焦点を当てた質問を通じて、思考と行動のクセを見極めることが効果的です。

# 具体的な質問の例

質問が思い浮かばないときは、[ソラ・アメ・カサというフレームワーク](https://president.jp/articles/-/52846) を利用すると質問しやすいです。

例：
「当時どういう状況でしたか？」 -> ソラ
「その状況が続くと、どうなると予想していましたか？」 -> アメ
「どのように行動しましたか？」 -> カサ

具体的な例として、エンジニア未経験でSESとして3年経験し、最近では3人程度をリードした経験がある方と面接をしたと仮定します。

### 未経験から技術をキャッチアップしたエピソード
質問: 「未経験で入社した際、分からないことだらけだったと思います。どのようにして理解を深めていったんですか？」
回答: 「まず2ヶ月間Javaの研修がありました。その後はすぐ現場に配属され、ほとんど分からないまま手探りで学習しました。」

質問: 「タスクはどのようにアサインされたんですか？」
回答: 「当時のメンバーは5名で、上司のような人はいましたがほとんどタスク分解をしてくれなくて困っていました。何をしたらいいかは、依頼主であるお客様に情報元があると考え、自分でお客様と会話して何をやるべきかをすり合わせて自分でタスクを決めていました。」

質問: 「大変でしたね。その上司の方へ怒りの感情が湧いても不思議じゃないと思うんですが、何かしらフィードバックなどしたんですか？」
回答: 「いえ、分からないことはその上司に聞けば優しく丁寧に教えてくれたり良い面もあったので、特に怒りは感じませんでした。挑戦する環境があり、教えてくれる人もいるので、まあなんとかなるだろうと思っていました。また自身の成長のチャンスだなと捉えて楽しく仕事していました。」

このようなエピソードがあったとします。この話から分かることがいくつかあります。

### 思考のクセの評価
- 研修直後に無理やりアサインされた現場にも関わらず、環境に文句を言うのではなく、環境を利用し自身の成長を通して成果を出そうと考えることができている点で、逆境に強くResilienceが高そう
- 「まあなんとかなるだろう」という発言から、ある程度自分に自身があり、自分ならうまくいくはずという思考がEfficacyとOptimismの高さを示している

### 行動のクセの評価
- 初めてのプロジェクトでいきなり顧客と直接会話している点から、好奇心が高そう
- またよくわからない環境で物事を整理するため顧客と会話し、実際にタスク分解まで至っている点から、胆力が一定以上ありそう
- 元上司の仕事のやり方を内省し、自身の部下への仕事の方法を改善しており、洞察力が高そう

ここから更にいろんなエピソードを聞いて多面的にクセを明らかにしていくことで、より確度の高い見極めができます。

### 特性のバランス評価
会社のフェーズやチームによって、どの要素を重視するかは変わってくると思います。

各特性が過度になった場合のリスクと、適切な状況での価値をバランス良く評価します。例えば、楽観性が高い人はリスクを見落とすことがあるため、その点を踏まえた上でどの程度の楽観性が適切かを検討します。

このようなエピソードを通じて、候補者が未知の環境でどのように対応し、技術や業務を学び取ったかを詳細に理解することができます。これらの質問と回答は、候補者の思考と行動のクセを深く掘り下げるのに役立ちます。

# まとめ

このように思考と行動のクセの切り口で過去のエピソードを深堀りすることで、候補者の特性を分析することができます。
あくまで切り口のひとつではありますが、この観点だけでも求めている人の特性をディスカッションする、面接で実践してみる、入社後に答え合わせをしてみる、など様々な活用ができると思うので、ぜひ使ってみてください。
BigQuery MLモデルを使用した低レイテンシ予測パイプラインのイメージ

## はじめに
今回はデータサイエンティストやデータエンジニアがBigQuery MLモデルを作成し、予測結果を提供するMLパイプラインの構成について、備忘録として残します。この記事では、REST APIアプリケーションを使用して、個々のユーザーIDの予測を100ミリ秒以下のレイテンシで提供する方法を解説します。

## ソリューションの全体フロー

以下の図は、データの流れを示しています。各ステップで使用されるツールや必要なロールも含めています。

```
+--------------------------------------+
|           BigQuery MLモデル            |
+--------------------------------------+
              |       
              v       
+--------------------------------------+
|         Dataflow パイプライン           |
|     (BigQueryIO, BigtableIO)         |
+--------------------------------------+
              |       
              v       
+--------------------------------------+
|            Bigtable                  |
+--------------------------------------+
              |       
              v       
+--------------------------------------+
|         REST APIアプリケーション      　   |
|   (Bigtable Readerロールを付与)        　|
+--------------------------------------+
```

### 使用するツールとサービスの説明

1. **BigQuery MLモデル**:
   - **説明**: BigQuery MLを使用すると、BigQuery内で直接機械学習モデルのトレーニングと予測を行うことができます。SQLクエリだけで機械学習を操作できるため、データサイエンティストやアナリストにとって非常に使いやすいです。
   - **用途**: ユーザーデータを基に予測モデルを作成し、予測結果を生成します。

2. **Dataflow パイプライン**:
   - **説明**: Apache BeamをベースにしたGoogle Cloudのサービスで、バッチおよびストリーミングデータ処理に使用されます。Dataflowはデータの移動と変換を自動化し、スケーラブルで管理しやすいデータパイプラインを提供します。
   - **使用ツール**:
     - **BigQueryIO**: DataflowからBigQueryデータセットを読み込むためのI/Oツールです。MLモデルから予測結果を取得します。
     - **BigtableIO**: DataflowからBigtableにデータを書き込むためのI/Oツールです。予測結果をBigtableに保存します。
   - **用途**: BigQuery MLモデルから予測結果を取得し、それをBigtableに書き込みます。

3. **Bigtable**:
   - **説明**: Google CloudのNoSQLデータベースで、高スループットと低レイテンシの読み書き性能を提供します。大量のデータを効率的に処理することができます。
   - **用途**: Dataflowパイプラインからの予測結果を保存し、低レイテンシでのアクセスを提供します。

4. **REST APIアプリケーション**:
   - **説明**: ウェブアプリケーションフレームワーク（例：FlaskやFastAPI）を使用して構築されたAPIで、クライアントからのリクエストに応じてデータを提供します。
   - **用途**: Bigtableから予測結果を取得し、クライアントに返答します。100ミリ秒以下のレイテンシで予測結果を提供することを目指します。
   - **ロール**: アプリケーションサービスアカウントにBigtable Readerロールを付与します。

### サービスアカウントとロールの設定

- **Dataflow Workerロール**: Dataflowパイプラインを実行するためのサービスアカウントに付与します。
- **Bigtable Readerロール**: APIアプリケーションのサービスアカウントに付与します。

## まとめ

このソリューションでは、BigQuery MLモデルから予測結果を取得し、Dataflowパイプラインを使用してBigtableに保存します。APIアプリケーションはBigtableから予測結果を取得し、ユーザーに対して100ミリ秒以下のレイテンシで提供します。この方法により、リアルタイムに近いレスポンスを実現し、エンドユーザーに対して迅速な予測結果を提供することができます。


この記事がBigQuery MLモデルを使用した低レイテンシ予測パイプラインの理解と実装に役立つことを願っています。質問やフィードバックがあれば、ぜひお知らせください。
Poetry環境+VSCodeでJupyter Notebookを使って実行するとカーネルのエラーになる

## エラー内容

Poetry環境を作成し、VSCodeでカーネルを選択して.ipynbのセルを実行しようとしたところ、下記のエラーになった。

選択したカーネル
![スクリーンショット 2024-06-17 12.06.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506559/2ee671ca-a5a4-9f9d-b3cb-415187bcda1b.png)

エラー文
```
'Python 3.12.3' でセルを実行するには、 ipykernel パッケージが必要です。
次のコマンドを実行して、'ipykernel' を Python 環境にインストールします。
コマンド: '/usr/local/bin/python3 -m pip install ipykernel -U --user --force-reinstall'
```

## 解消法

ググってもよくわからなかったのでChatGPTにきいてみると、仮想環境用のカーネルを登録すればよいとのことだったので、実施してみると無事一発で解消した。

VSCodeのJupyter Notebook拡張機能が、Poetryで作成した仮想環境のipykernelを認識していないことで発生するエラーらしい。

### 1. Poetry環境で必要なパッケージをインストール
まず、Poetryでipykernelをインストールする必要があります。ターミナルを開いて、プロジェクトディレクトリに移動し、以下のコマンドを実行します。
```
poetry add ipykernel
```
### 2. 仮想環境のカーネルを登録
次に、Poetryの仮想環境をJupyterに認識させるため、仮想環境のPython実行ファイルを使ってカーネルを登録します。
```
poetry run python -m ipykernel install --user --name=your_env_name --display-name "Python (your_env_name)"
```
ここで、your_env_nameは仮想環境の名前です。好きな名前を付けてください。
### 3. VSCodeでカーネルを選択
VSCodeを再起動し、.ipynbファイルを再度開きます。次に、ノートブックの右上にあるカーネル選択メニュー（「Python 3.12.3」などと書かれている部分）をクリックし、先ほど登録したカーネルを選択します。

### 4. 必要な拡張機能の確認
VSCodeに以下の拡張機能がインストールされていることを確認します。

Jupyter
Python
これらがインストールされていない場合、VSCodeの拡張機能マネージャからインストールしてください。

### 5. 再試行
これで、.ipynbファイルのセルを実行して、エラーが解消されているか確認します。

## 結果

上記を試した結果、「Jupyter Kernel...」というのが選べるようになり、そこに先程作成したカーネルが表示されるので、それを選択すればよい。
ただ、最初に示した`.venv/bin/python`のカーネルを選択したままでも通るようになった。
![スクリーンショット 2024-06-17 12.26.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506559/496f2268-3985-4f82-4a5d-68103e029e3a.png)

## まとめ

エラーを投げるとだいたい1発で解消に導いてくれるので、ChatGPT先生はすごい。
同様のエラーがおきた方の参考になれば嬉しいです。
<input type="number">のスピンボタンに文字列を表示させたい

# コード html
```html
<div class="custom-input-wrapper">
    <input type="number" id="myNumber" min="1" max="100" step="1" value="1" class="transparent-input">
    <span class="custom-input-label" id="levelLabel">レベル1</span> 
</div>

<style>
    .custom-input-wrapper {
        position: relative;
        display: inline-block;
    }
    .custom-input-wrapper input {
        width: 150px; 
        padding-left: 60px; 
        box-sizing: border-box;
    }
    .custom-input-label {
        position: absolute;
        left: 10px; 
        top: 50%;
        transform: translateY(-50%);
        pointer-events: none;
    }
    .transparent-input {
        color: transparent;
    }
    .transparent-input::selection {
        color: transparent;
    }
</style>

```

# コード javascript
```javascript
    const numberInput = document.getElementById('myNumber');
    const levelLabel = document.getElementById('levelLabel');

    function updateLabel() {
        const value = numberInput.value;
        levelLabel.textContent = `レベル${value}`;
    }

    numberInput.addEventListener('input', updateLabel);
    updateLabel(); // 初期値の設定と表示の更新
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/c8575d20-56e9-38f1-f9f4-6d4f3a0e8775.png)
brew install --cask pgadmin4 コマンド brew install postgresqlコマンド違い



## PostgreSQLとpgAdmin4インストールコマンド比較：詳細解説

PostgreSQLは高性能なオープンソースデータベースとして人気があり、pgAdmin4はPostgreSQLを管理するためのGUIツールです。

本記事では、`brew install postgresql`と`brew install --cask pgadmin4` コマンドの違いを詳細に比較し、それぞれの用途を明確にします。

### 1. コマンド詳細

#### 1.1 `brew install postgresql`

このコマンドは、PostgreSQLの**サーバー**部分をインストールします。

* インストールされるもの
    * PostgreSQLサーバーバイナリ
    * 関連ツール (e.g., psql, createdb)
    * 設定ファイル
* インストール後の状態
    * コマンドラインからPostgreSQLサーバーを起動・停止・管理可能
    * GUIツールでの操作は不可
    * データベースの作成・管理は`psql`などのコマンドラインツールで行う

#### 1.2 `brew install --cask pgadmin4`

このコマンドは、PostgreSQL管理用GUIツールである**pgAdmin4**をインストールします。

* インストールされるもの
    * pgAdmin4アプリケーション
    * 関連ファイル
* インストール後の状態
    * アプリケーションを起動することで、GUI上でPostgreSQLデータベースを操作可能
    * データベースの作成・編集、クエリ実行、ユーザー管理などが容易
    * コマンドライン操作にも対応

### 2. 比較表

| 項目 | `brew install postgresql` | `brew install --cask pgadmin4` |
|---|---|---|
| インストール対象 | PostgreSQLサーバー | pgAdmin4 (GUIツール) |
【サクラエディタ】便利なショートカットキー

エディタの中でもよく利用しているため、
サクラエディタのショートカットについてまとめました。

なかでもGrepや矩形選択は便利でよく使用しています。

## ショートカットキー一覧
### 基本
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [X] ／ [F7] | 切り取り | 
| [Ctrl] + [C] ／ [F8] | コピー | 
| [Ctrl] + [V] ／ [F9] | 貼り付け | 
-------
### ファイル操作系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [N] | ファイルの新規作成 | 
| [Ctrl] + [O] | ファイルを開く | 
| [Ctrl] + [F4] | ファイルを閉じる | 
| [Ctrl] + [S] | 保存 | 
| [Ctrl] + [Shift] + [S] | 新規保存 |
-------
### 編集系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [Z] | 元に戻す | 
| [Ctrl] + [Y] | やり直し | 
| [Alt] + [A] | 選択行のソート（昇順） | 
| [Alt] + [D] | 選択行のソート（降順） | 
| [Alt] + [M] | 重複行の削除（連続している完全に同じ内容の行に限る） | 
| [Ctrl] + [E] | 1行切り取り | 
| [Ctrl] + [Shift] + [E] | 1行削除 | 
-------
### カーソル移動系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Home] | 行頭へ移動 | 
| [End] | 行末へ移動 | 
| [Ctrl] + [Home] | ファイルの先頭へ移動 | 
| [Ctrl] + [End] | ファイルの最後へ移動 | 
-------
### 選択系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [A] | すべて選択 | 
| [F6]、[方向キー↑↓←→] ／ [Shift] + [方向キー↑↓←→] | 範囲選択 | 
| [Shift] + [F6]、[方向キー↑↓←→] ／ [Alt] + [方向キー↑↓←→] | 矩形選択 | 
-------
### 検索系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [F] | 検索 | 
| [F3] | 次へ検索 | 
| [Shift] + [F3] | 前へ検索 | 
| [Ctrl] + [R] | 置換 | 
| [Ctrl] + [G] | Grep | 
-------
### ウインドウ操作系
| ショートカットキー | 説明 |
| ------- | ------- |
| [Ctrl] + [Tab] | タブ移動 | 
| [Ctrl] + [Shift] + [Tab] | タブ移動（逆方向） | 
-------
### その他
| ショートカットキー | 説明 |
| ------- | ------- |
| [Shift] + [F1] | コマンド一覧を表示 |
デザインの宝庫！おすすめWEBギャラリーサイトとデザイン本


## 挨拶

こんにちは！今日は、デザインの参考を探している方に向けて、私が普段利用しているおすすめのWEBギャラリーサイトとデザイン本を紹介したいと思います。クリエイティブなアイデアを広げるための参考になること間違いなしです！海外のものが多いのは、WEBデザインは数をこなして覚えるものだと考えており数の多い海外が適していると感じているためです。

## おすすめのWEBギャラリーサイト

### 1. Awwwards
[Awwwards](https://www.awwwards.com/)は、優れたウェブデザインを評価し、表彰するプラットフォームです。世界中のデザイナーが投稿する最新のデザイン作品を閲覧することができ、インスピレーションを得るのに最適な場所です。

### 2. Behance
[Behance](https://www.behance.net/)は、Adobeが運営するクリエイティブなポートフォリオサイトです。ウェブデザインだけでなく、グラフィックデザイン、イラスト、写真など、さまざまなジャンルの作品を見ることができます。ユーザーがプロジェクトを公開し、フィードバックを受け取ることもできるので、コミュニティとの交流も楽しめます。

### 3. Dribbble
[Dribbble](https://dribbble.com/)は、デザイナーやクリエイターが自分の作品を共有するためのプラットフォームです。シンプルで美しいデザインが多く、UI/UXデザインのトレンドを追うのに役立ちます。気に入ったデザイナーをフォローすることで、継続的にインスピレーションを得ることができます。

### 4. SiteInspire
[SiteInspire](https://www.siteinspire.com/)は、洗練されたウェブデザインのギャラリーサイトです。カテゴリ別に整理されているため、特定のデザインスタイルや業界に絞って検索することができます。クリーンでモダンなデザインを探している方におすすめです。

### 5. CSS Design Awards
[CSS Design Awards](https://www.cssdesignawards.com/)は、クリエイティブなウェブデザインを表彰するサイトで、ユーザーからの評価を受けて優れたデザインが紹介されます。新しい技術やトレンドを取り入れた作品が多く、デザインの最新情報をチェックするのに最適です。

## おすすめのデザイン本

### 1. 『Don't Make Me Think』 by Steve Krug
ユーザーエクスペリエンス（UX）デザインの基本を学ぶための必読書です。シンプルで実用的なアプローチで、ウェブデザインを改善するためのヒントが満載です。
[Amazonで見る](https://www.amazon.co.jp/dp/0321965515)

### 2. 『The Design of Everyday Things』 by Don Norman
デザインの原理と心理学を学べる一冊です。日常的な製品のデザインに関する洞察が豊富で、ウェブデザインにも応用できる概念がたくさん詰まっています。
[Amazonで見る](https://www.amazon.co.jp/dp/0465050654)

### 3. 『Refactoring UI』 by Adam Wathan & Steve Schoger
UIデザインを改善するための具体的な方法を紹介する本です。美しいデザインを作るための実践的なテクニックが多数掲載されています。
[公式サイトで購入](https://refactoringui.com/book/)

### 4. 『Design Systems』 by Alla Kholmatova
デザインシステムを構築するためのガイドブックです。統一感のあるデザインを作るための手法やツールについて詳しく解説されています。
[Amazonで見る](https://www.amazon.co.jp/dp/1491972422)

### 5. 『Steal Like an Artist』 by Austin Kleon
クリエイティビティを高めるためのインスピレーションとアイデアを提供する本です。他のアーティストやデザイナーから学び、自分の作品に取り入れる方法について書かれています。
[Amazonで見る](https://www.amazon.co.jp/dp/0761169253)

### 6.  『Webデザイン良質見本帳[第2版] 目的別に探せて、すぐに使えるアイデア集』 by久保田 涼子
この本は、目的別にウェブデザインのアイデアを探すことができる実用的なガイドです。具体的な事例やデザインのポイントが豊富に紹介されており、すぐに使えるアイデアが満載です。実際のプロジェクトに応用しやすいので、実務での活用度も高い一冊です。
[Amazonで見る](https://amzn.asia/d/9QRBsUa)
### 7. 『ノンデザイナーズ・デザインブック』 by Robin Williams
デザインの基本原則を学ぶための定番書籍です。非デザイナーにもわかりやすく、デザインの基本を理解するための実践的なアドバイスが満載です。デザインに自信がない方でも、読むことでデザインの基礎力を高めることができます。
[Amazonで見る](https://amzn.asia/d/g5vC4TS)
## まとめ

デザインのインスピレーションを得るためには、優れたウェブギャラリーサイトを活用し、参考になるデザイン本を読むことが大切だと考えています。Awwwards、Behance、Dribbbleなどのサイトで最新のデザインをチェックしながら、紹介したデザイン本で知識を深めていくと、クリエイティブなスキルが向上します。ぜひこれらのリソースを活用して、素晴らしいデザインを作り上げていきたいですね！
それでは、また次回の記事でお会いしましょう！
【ChatGPT＋DALL-E3】【Dream Machine】の動画をつなげる方法


　どうも、カーブミラーです。

　今回は、Dream Machineの動画をつなげる方法です。もちろんChatGPT（GPT-4o）で行ないます。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はありません。あしからず。
:::

　いやぁ、
　　Dream Machine楽しい！

　でも
　　Prompt入れたら
　　　結構待たされます。

　課金すれば
　　優先的に処理して
　　　もらえますけど、
　　　　懐がさみしい😭
***
　さて、
　　今回は、
　　　そんなDream Machineで
　　　　作成した動画同士を
　　　　　つなげたいと
　　　　　　思います。

　もちろん、
　　ChatGPTで。

　ここでは
　　単純なつなげ方を
　　　示します。

　まずは、
　　セッションが
　　　GPT-4oになっていることを
　　　　確認します。

　次に
　　つなげたい順に
　　　ふたつの動画をアップロード。

```Text:動画と動画をつなげる
このふたつをひとつにして
```
　を入れて送信します。

　Code Interpreterが
　　動いて、少しすると
　　　ダウンロードリンクが
　　　　出てきます。

　それをタップして
　　ダウンロード。

　はい、終わり。
***
　ここでは
　　単純につなぎましたが、
　　　このままでは、
　　　　ブツッと次の動画に
　　　　　切り替わってしまいます。

　もちろん、
　　それがいい味を
　　　出す場面もあります。

　しかし、
　　同一シーンの長尺動画を
　　　作るには、まずいですね。

　次回は、
　　それを書きましょう。

　みなさんの
　　作品制作の糧に
　　　なれば、幸いです。

　今回は、ここまで。
Feynman伝搬関数の書き方

```LaTeX:.tex
\newcommand*{\slanted}[1]{\tikz[baseline=(T.base)]{
        \node[inner sep=-2pt,outer sep=0pt,xslant=0.50](T){$\Delta$}}}
% ↓↓↓
\slanted
```
![Feynman伝搬関数-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817756/1f757597-4c3e-61b5-00c2-1796d6252e2b.png)
Python+poetry環境でpre-commitフックを実行する

# 環境
OS: Ubuntu22.04
Python 3.11
poetry 1.8.2

# 前提条件

- poetryを用いてpythonの環境構築が終わっている
- プロジェクト内で`git init`などGithubでコード管理を行う準備ができている

# やったこと

1. 必要なパッケージをインストールする

    poetryを用いて依存パッケージをインストールするには`poetry add`を使用します。
    pre-commitの他に、コードの修正に必要なパッケージもインストールしておきます。
    
    ```bash
    # -Dをつけると、devDependenciesになる
    poetry add -D pre-commit flake8 black isort
    ```

    それぞれの役割は以下のとおりです。
    - isort: モジュールのインポート順序を修正
    - flake8: フォーマットの検査
    - black: 自動でフォーマットを修正
    
1. `.pre-commit-config.yaml`を作成/編集

    以下のコマンドで`.pre-commit-config.yaml`が作成されます。
    ```bash
    poetry run pre-commit sample-config > .pre-commit-config.yaml
    ```

    <details><summary>.pre-commit-config.yaml編集前</summary>
    
    ```.pre-commit-config.yaml
    # See https://pre-commit.com for more information
    # See https://pre-commit.com/hooks.html for more hooks
    repos:
    -   repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v3.2.0
        hooks:
        -   id: trailing-whitespace
        -   id: end-of-file-fixer
        -   id: check-yaml
        -   id: check-added-large-files
    ```

    </details>

    <details open><summary>.pre-commit-config.yaml編集後</summary>

    ```.pre-commit-config.yaml
    repos:
      - repo: https://github.com/pre-commit/pre-commit-hooks
        rev: v3.2.0
        hooks:
          - id: trailing-whitespace
          - id: end-of-file-fixer
          - id: check-yaml
          - id: check-added-large-files
      - repo: https://github.com/pycqa/flake8
        rev: 7.0.0
        hooks:
          - id: flake8
            additional_dependencies:
              - flake8-isort
            args: ["--max-line-length=150", "--ignore=W293 E203"]
      - repo: https://github.com/psf/black
        rev: 24.4.2
        hooks:
          - id: black
            language_version: python3.11
      - repo: https://github.com/pycqa/isort
        rev: 5.13.2
        hooks:
          - id: isort
            name: isort (python)
    ```
    
    </details>

# 結果

上記を行ったあと、commitをすると以下のような出力が得られます。

```bash
git commit -m "コミットメッセージ"
> Trim Trailing Whitespace.................................................Passed
> Fix End of Files.........................................................Passed
> Check Yaml...........................................(no files to check)Skipped
> Check for added large files..............................................Passed
> flake8...................................................................Passed
> black....................................................................Passed
> isort (python)...........................................................Passed
```

なにか問題があるときは、`passed`の代わりに`Failed`と表示され、問題がある箇所を教えてくれます。
BigQueryの変更データキャプチャ（CDC）を活用したデータ移行の最適化


## CDCとは？

変更データキャプチャ（CDC）は、データベースの変更箇所を特定し、それを別のデータベースやデータウェアハウスに適用する技術です。CDCには、トリガーベースやログベースなどの方法があります。ログベースのCDCは、トランザクションログから変更箇所を抽出するため、リアルタイム性が高く、データの同期や更新が効率的に行えます。

## BigQueryでのCDCの最適化手法

### 1. CDCレコードをステージングテーブルに挿入する

まず、各新規CDCレコードと対応する操作タイプ（INSERT、UPDATE、DELETE）をリアルタイムでステージングテーブルに挿入します。ステージングテーブルは、変更データや一時的なデータを保存するためのテーブルです。

```sql
-- ステージングテーブルにCDCレコードを挿入
INSERT INTO `project.dataset.staging_table` (record_id, operation_type, updated_at)
VALUES ('12345', 'UPDATE', CURRENT_TIMESTAMP())
```

### 2. 定期的にDML MERGEを使用する

次に、定期的にDML MERGEを使用して、レポートテーブルに対して複数のDML操作（INSERT、UPDATE、DELETE）を同時に実行します。これにより、計算オーバーヘッドが削減され、パフォーマンスが最適化されます。

```sql
-- レポートテーブルに対するDML MERGE操作
MERGE `project.dataset.report_table` AS T
USING `project.dataset.staging_table` AS S
ON T.record_id = S.record_id
WHEN MATCHED AND S.operation_type = 'UPDATE' THEN
  UPDATE SET T.column1 = S.column1, T.column2 = S.column2, T.updated_at = S.updated_at
WHEN MATCHED AND S.operation_type = 'DELETE' THEN
  DELETE
WHEN NOT MATCHED AND S.operation_type = 'INSERT' THEN
  INSERT (record_id, column1, column2, created_at)
  VALUES (S.record_id, S.column1, S.column2, S.created_at)
```

## なぜこれらの手順が有効なのか？

1. **リアルタイムのデータキャプチャ**:
   - CDCレコードをステージングテーブルにリアルタイムで挿入することで、ソースシステムの変更を即座にキャプチャできます。

2. **効率的なデータ適用**:
   - 定期的なDML MERGE操作を使用することで、レポートテーブルへのデータ適用を効率化し、計算オーバーヘッドを削減できます。

これにより、BigQueryのレポーティングテーブルで変更を最小限のレイテンシで利用でき、パフォーマンスを最適化することが可能です。

## まとめ

BigQueryでのCDC処理を最適化するためには、ステージングテーブルを使用して変更データをリアルタイムでキャプチャし、定期的にDML MERGEを使用してレポートテーブルにデータを適用することが効果的です。これにより、低レイテンシでリアルタイムのクエリアクセスが可能となり、パフォーマンスが向上します。
新卒が実装前のコードリーディングの大切さに気づいた話

## はじめに
4月から株式会社HRBrainの新卒エンジニアとして入社しました！
インターンとしてほんの少し開発に携わっていましたが、本格的に開発するのは初めてです👶🏻
そんな私が、入社2ヶ月でコードリーディングの大切さに気づいた話について記事にしてみました。

## 4月
4月中旬から開発に携わり始め、いくつかタスクをもらいました。
その時の心境は「早く成果を出さないと」という焦りの気持ちでした。
 **「早く」** という気持ちからコードリーディングを「何となくこのあたり変更すればいけそう」という状態で終え、実装に移っていました。

コードが理解できていないので以下のような状態でした。
* どこに影響があるのか不明確
* 具体的な実装案が思い描けない
* 曖昧な質問になり、仕様・実装方法が定まらない

そのため、**考慮漏れで手戻りが多くなり、その日の作業の半分以上が無駄になる**ということもありました。

この時は、技術や知識不足で開発に時間かかるなあと感じていました。（もちろんそれも原因の1つです😖）
しかし、改めて自分のタスクの進め方を振り返ると、技術や知識以外にも問題があると感じました。
それが **「コードリーディングが甘すぎる」** でした。早さを求めて実装した結果、非効率的な進め方をしていたことに気が付きました。


## 5月
効率的に開発できていないため、改善策として、**実装前にコードリーディングに時間をかけてみるのが良いのではないか**と考え始めました。しかし、ふわっとそうしたら良いのかなくらいの温度感で、時間をかけることで効率が上がるのか不安でした。

そこで、色々な方々と1on1をする機会を活用して相談することにしました。
相談した結果、「コードリーディングが開発スピードを上げるきっかけになりそう」と複数の方からアドバイスいただき、自分も自信を持ってトライしようと思えました。
そこからコードリーディングに時間をかけ、できるだけ手戻りが少なくなるように意識して取り組むようになりました。

## 1ヶ月間実践した結果
「このあたりを変更すればいけそう」から **「変更箇所+方針・実装方法+影響範囲を明確」** にして実装を始めるようにした結果

* 実装の時点では手を動かすだけ、さくさく進む
* 手戻りがほとんどない。気になることは実装時点では解決済み
* 質問が具体的になる
* 気づいたら今回対象じゃないところにも影響が...ということが減った

これまでの開発では、なんとなくで進めていたので実装期間が見えなかったですが、工数を見積もれるようになりました。（実装がサクサク進むので気持ちとしても楽でした）

## さいごに
早めにコードリーディングの大切さに気づけてよかったと思っています。はじめはコードを追うことにたくさん時間がかかっていましたが、だんだんコードへの理解や追い方がわかってきてスピードが上がってきました。
コードリーディングのスピードが上がると開発工数全体で見てもとても効率的になってきたと感じます。

## おまけ
今回、定期的に振り返りを行っていたため、問題にも気づき早めに対処することができました！
このことからも振り返る機会というのがとても大切だと感じています。
私は2週間の目標を決めて振り返りから次の目標を決めるというサイクルを引き続き続けていたいと思います。


## PR
株式会社HRBrainでは一緒に働くメンバーを募集しています！気になる方はぜひ御覧ください。
https://www.hrbrain.co.jp/recruit
OpenSiv3Dのremove_if でメンバ変数の条件で削除する


下記クラスで動的配列を作ったとき、a < 5 の要素のものだけ削除する

```C++:TEST.h
class Test
{
public:
	int a, b;
	Test() :a(0), b(0)
	{}
	Test(int a, int b = 0)
	{
		this->a = a, this->b = b;
	}
};

```

:::note

Array\<Test\> tests; // ここにランダムで値を適当にいれる


**tests.remove_if([&](auto a) { return a.a < 5; });** // **a<５** の要素のみ削除

:::


以下、デバッグ表示込みの実装コード

```c++:remove_if_TEST.cpp

# include <Siv3D.hpp> // Siv3D v0.6.14

class Test
{
public:
	int a, b;
	Test() :a(0), b(0)
	{}
	Test(int a, int b = 0)
	{
		this->a = a, this->b = b;
	}
};

void Main()
{
	// 背景の色を設定する | Set the background color
	Scene::SetBackground(ColorF{ 0.6, 0.8, 0.7 });

	Array<Test> tests, temp;
	for (size_t i = 0; i < 10; i++)
	{
		tests << Test{ Random(10),7 };
	}
	temp = tests;
	tests.remove_if([&](auto a) {return a.a < 5; }); //aが5未満の要素だけ削除 bは関係なし

	String tempStr = U"";
	for (auto& a : temp)
	{
		tempStr = tempStr + U"[ {},{} ]"_fmt(a.a, a.b);
	}
	String deletedStr = U"";
	for (auto& a : tests)
	{
		deletedStr = deletedStr + U"[ {},{} ]"_fmt(a.a, a.b);
	}
	s3d::Print << U"[a,b]" << tempStr;
	s3d::Print << U"  a < 5  のみ削除";
	s3d::Print << U"[a,b]" << deletedStr;


	while (System::Update())
	{
	}
}

```
実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76087/9ff633b1-02aa-4626-cb46-e304a6ffe834.png)
Apple Vision Pro（visionOS2）のARKitで追加された新機能とアップデートについて

## Apple Vision Pro の visionOS 2 で提供される機能
2024年秋頃に正式にリリースされる [visionOS 2](https://developer.apple.com/documentation/visionos-release-notes/visionos-2-release-notes ) は現在、ベータ版)としてリリースされています。今回、ARKitで提供された基本的な機能とvisionOS 1.xでリリースしている機能のバージョンアップについて紹介します。

## 新機能
### Room tracking（ルーム トラッキング）
https://twitter.com/tokufxug/status/1802506948975472761

Room tracking（ルームトラッキング）は、visionOS 2のARKitに追加された機能です。部屋内の境界を識別することができます。この情報から壁と床の正確な位置情報を計算します。詳細情報について以下の記事をごらんください。

https://1planet.co.jp/tech-blog/applevisionpro-oneplanet-visionos2-arkit

### Object tracking （オブジェクトトラッキング（物体追跡））

https://twitter.com/tokufxug/status/1800766575869563151

現実世界にあるアイテムをアンカーとして使用できるようにする機能です。日常のオブジェクトを見ただけで有用な情報を表示させたり、家電製品やデバイスにデジタルのマニュアルを表示するようなことが可能です。詳細情報について以下の記事をごらんください。

https://1planet.co.jp/tech-blog/applevisionpro-oneplanet-visionos2-object-tracking

## アップデート
### Plane detection（平面検出）
![Plane detection（平面検出）](https://storage.googleapis.com/studio-cms-assets/projects/Kwa5KvdJOX/s-1624x788_v-fms_webp_39b4b744-48a3-4668-9f5e-c94cc9180daf.webp "Plane detection（平面検出）")
visionOS 1.xでは検出できなかった、「斜め」による平面の検出がvisionOS2では、できるようになりました。

### World tracking（ワールドトラッキング）
World tracking（ワールドトラッキング）は、照明の明るさや暗さの変化を検知する仕組みを追加しました。システム側がWorld tracking（ワールドトラッキング）が十分に機能していないことを検知します。十分に機能していない場合、空間内の位置ではなく、向きの変更によるトラッキングに切り替わります。


### Hand tracking（ハンドトラッキング）

https://twitter.com/tokufxug/status/1802261536867787121

visionOS 2では、Hand tracking（ハンドトラッキング）がvisionOS 1.xと比較するとスムーズに動作します。Apple Vision Proのディスプレイのリフレッシュ・レートに合わせて、Hand tracking（ハンドトラッキング）のデータ（HandAnchor）が送信されるようになりました。

アップデートの詳細については、以下の記事をご覧ください。
https://1planet.co.jp/tech-blog/applevisionpeo-oneplanet-visionos2-arkit-verup-dd3edb5c-3453-20a5-2a02-102999b6f4f2
Discord.pyで起動時に特定の名前のチャンネルでメッセージを出す方法

愛犬アレックス（アイコンの犬）「お腹すいたわん、でも、飼い主がいないわん。困ったわん」
🐶「そうだ！discord経由で連絡すればいいわん！」
🐶「この間、建てた家族用のサーバーを使うわん！」
🐶「でも、キーボード打てないわん……困ったわん……」
🐶「そうだ、この間ご主人がくれたこのボタン、discordのbotになってるって言ってたわん！」
🐶「押してみよ！」

U･ω･U）ﾉ凸”ﾎﾟﾁｯ

bot「（シーン）」
ワシ「（シーン）」
🐶「（シーン）」

🐶「使えないやんけ！！！！！」

こんな🐶を救うために、今日はDiscord.pyを使用して
実行ファイルの起動時、特定の名前のチャンネルにメッセージを出す方法を解説してます！

# 前提条件・実行環境
- python３以上
- discord.pyのインストール
- disocrdでのアプリ作成・TOKENなどの取得
- botの権限周りの設定が完了している
- 投稿日現在は機能しているが、discordAPIのアップデートによる仕様変更の可能性あり

上記の環境設定が完了していることを前提とします。

# コードの内容
```python
import discord

TOKEN='your_token' #discordで取得したTOKEN

intents = discord.Intents.default()
intents.messages = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():

	ch_name = "一般" # ここで通知するチャンネル名を決定する

	for channel in client.get_all_channels():
		if channel.name == ch_name:
			await channel.send("ご飯をくれ！") #送信するメッセージ

client.run(TOKEN)
```
# 詳細説明
以下のPythonコードは、DiscordのBotを起動し、特定のチャンネルにメッセージを送信するプログラムです。コードの各部分を詳細に解説します。

1. **ライブラリのインポート**
   ```python
   import discord
   ```
   - `discord` ライブラリをインポートします。このライブラリはDiscord APIとやり取りするために使用されます。
2. **Botトークンの設定**
   ```python
   TOKEN = 'your_token'  # Discord Developer Portalで取得したBotのトークン
   ```
   - Discord Developer Portalで取得したBotのトークンを設定します。`your_token` の部分を実際のトークンに置き換えてください。

3. **インテンツの設定**
   ```python
   intents = discord.Intents.default()
   intents.messages = True  # メッセージ関連のインテンツを有効にする
   ```
   - `intents` は、Botがどの種類のイベントを受け取るかを設定します。`default()` メソッドでデフォルトのインテンツを取得し、`intents.messages = True` でメッセージ関連のイベントを有効にします。

4. **Discordクライアントの作成**
   ```python
   client = discord.Client(intents=intents)
   ```
   - `discord.Client` を初期化し、先ほど設定した `intents` を渡します。

5. **`on_ready` イベント**
   ```python
   @client.event
   async def on_ready():
       # Botが起動した際に呼び出されるイベント
       print(f'Logged in as {client.user}')  # ログインしたユーザーの名前を出力
   ```
   - `@client.event` デコレーターを使用して、Botが起動した際に実行される `on_ready` イベントを定義します。
   - `print(f'Logged in as {client.user}')` で、Botがログインしたことをコンソールに出力します。

6. **指定チャンネルへのメッセージ送信**
   ```python
   ch_name = "一般"  # ここで通知するチャンネル名を決定する

   # サーバー内の全チャンネルを取得し、指定されたチャンネル名と一致するチャンネルを探す
   for channel in client.get_all_channels():
       if channel.name == ch_name:
           await channel.send("起動しました")  # メッセージを送信
           break  # メッセージ送信後にループを終了
   ```
   - `ch_name` 変数に通知するチャンネル名を設定します。この例では `"一般"` というチャンネル名を使用しています。
   - `client.get_all_channels()` でサーバー内の全チャンネルを取得し、指定されたチャンネル名と一致するチャンネルを探します。
   - 一致するチャンネルが見つかったら、`await channel.send("起動しました")` でメッセージを送信し、`break` でループを終了します。

7. **Botの起動**
   ```python
   client.run(TOKEN)
   ```
   - `client.run(TOKEN)` でBotを起動し、Discordサーバーに接続します。

このコードを実行することで、Discordサーバーに接続し、指定されたチャンネルにメッセージを送信するBotが起動します。 `your_token` の部分を実際のBotトークンに置き換えてください。また、Botがメッセージを送信できるようにするために、サーバーで適切な権限を持っていることを確認してください。

# 終わりに
🐶「これでご主人を簡単に呼べるわん！」
🐶「でも、起動時にしか呼べないの困るわん…？？（次回予告）」
BigQueryのワイルドカードテーブルとは？

## はじめに
Google BigQueryは、スケーラブルなデータウェアハウスとして、大量のデータを効率的に処理するための強力な機能を提供しています。その中でも特に便利な機能の一つが「ワイルドカードテーブル」です。この記事では、ワイルドカードテーブルの基本的な使い方やその利点について解説します。

## ワイルドカードテーブルとは？
ワイルドカードテーブルは、テーブル名にアスタリスク（*）を使用して、特定のパターンに一致する複数のテーブルに対して一度にクエリを実行できる機能です。これにより、同じ構造を持つ複数のテーブルからデータをまとめて取得することができます。

## ワイルドカードテーブルの基本的な使い方
ワイルドカードテーブルを使用する際には、テーブル名の末尾にアスタリスク（*）を付けて指定します。また、各テーブルの末尾部分をフィルタリングするために、`_TABLE_SUFFIX`擬似列を使用します。

以下に、架空のテーブル名を使用した具体的な例を示します。

### 例：年度ごとの売上データをクエリする

例えば、各年度ごとの売上データを含むテーブルが次のように存在するとします。

- `project.dataset.sales_2020`
- `project.dataset.sales_2021`
- `project.dataset.sales_2022`

これらのテーブルから全ての年度のデータをクエリする場合、以下のようにワイルドカードテーブルを使用します。

```sql
SELECT product, revenue, _TABLE_SUFFIX as year
FROM `project.dataset.sales_*`
ORDER BY revenue DESC
```

このクエリでは、`project.dataset.sales_`で始まる全てのテーブルからデータを取得しています。また、`_TABLE_SUFFIX`を使用して各レコードがどの年度のテーブルから取得されたかを識別できます。

## エラーメッセージの対処方法

ワイルドカードテーブルを使用する際に、テーブル名の書き方に注意しないとエラーメッセージが表示されることがあります。例えば、次のようなクエリがあるとします。

```sql
SELECT product, revenue
FROM project.dataset.sales_*
ORDER BY revenue DESC
```

このクエリでは、テーブル名をバッククォート（`` ` ``）で囲んでいないため、次のようなエラーが発生します。

```
Syntax error: Expected end of statement but got "*" at [3:32]
```

この問題を解決するには、テーブル名をバッククォートで囲む必要があります。

```sql
SELECT product, revenue
FROM `project.dataset.sales_*`
ORDER BY revenue DESC
```

## まとめ

BigQueryのワイルドカードテーブルは、類似した名前を持つ複数のテーブルに対して一度にクエリを実行できる便利な機能です。テーブル名を正しく指定し、`_TABLE_SUFFIX`擬似列を使用することで、効率的にデータを取得することができます。エラーメッセージを参考にして、適切な形式でクエリを記述することが重要です。
【備忘録】GASで画面遷移を実装する

# はじめに

GASで画面遷移を実装する際の備忘録

# 

`index.html`と`viewer.html`間を移動できるようにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/b27cae53-2665-8dca-f050-1637769bf803.png)

~~~HTML:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
  </head>
  <body>
    <a href="<?= getAppUrl() ?>?page=viewer">Viewerへ</a>
    <a href="<?= getAppUrl() ?>?page=index">Indexへ</a>
  </body>
</html>
~~~

~~~HTML:viewer.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <a href="<?= getAppUrl() ?>?page=viewer">Viewer へ</a>
    <a href="<?= getAppUrl() ?>?page=index">Index へ</a>
  </body>
</html>
~~~

~~~JavaScript:コード.gs
function doGet(e) {
  let page = e.parameter.page;
  if (!page) {
    page = 'index';
  }

  var template = HtmlService.createTemplateFromFile(page);
  return template.evaluate();
}

function getAppUrl() {
  return ScriptApp.getService().getUrl();
}
~~~

# デプロイ

デプロイして実行すると、画面遷移できるようになりました。
画面遷移した際に、URLの末尾が変化していることがわかります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/a65ed2ef-ed08-cbf8-b81a-b488e97c7b24.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/37ed9d7c-3ff9-73d3-d5ad-49595554d07f.png)
【転職日記】薄給からの脱却【年収300万⇒400万】

## はじめに
本記事は個人を特定されることを防ぐため、年収・業務内容等はぼかしております。
ご了承ください。

## 利用した転職サイトorエージェント
・Geekly（今回の転職ではこちら経由で内定が決まりました:relaxed:）
・転職ドラフト
・levtechキャリア

## 経歴（めちゃ簡単に）
【業種】
・SES：2年
・SIer：1年

【開発工程・言語】
・基本設計（微経験程度）
・詳細設計・開発・テスト一通り
・java,php

## 選考結果
・応募　100社
・書類選考通過　10社
・一次面接通過　5社
・最終面接辞退　3社
・内定　2社

よく同じような転職記事に書類選考通過から記載をしている人が多く、実際どのくらいの応募感で面接まで進んでいるか不透明だと感じたので応募数も記載しております。

## 感想
応募はとにかく数撃てば当たる精神でしたほうが良いと感じました。
この中小には不通過で、この大手には通過するということも結構ありました。
そのためとにかく業務内容や働き方が少しでもマッチすると感じた企業様は応募することをおすすめします。
また私の場合は在職中に転職活動をしておりましたので、不通過時でも「まぁ現職あるしいいか（ぼけーっ:rolling_eyes:）」って感じのメンタルを保つことができました。
可能であれば在職中の転職がおすすめです。メンタルダメージが最小限だったように思います。

正直、今の時代終身雇用でもないですし、年収も上がりづらいのに長く勤務する方はもったいないと思います。向上心もあり年収も上げたい方はぜひ転職エージェントに登録しましょう！（※在職中もフォローしてもらえるのでおすすめです:relaxed:

## 余談（転職最大の難所、退職意向を伝える）
個人的に転職活動で一番難易度が高いと思う段階が退職意向を伝える段階だと思っています。
やっぱり退職意向を伝えるのってお互いに気まずいです。。。:frowning2:
私が実際にやったこととしては
①上司に相談事があるという名目でMTGを設定する
②退職日、転職先が決まっていることを説明する（言い切る形に近いです）
　⇒この時会社の不満とかぶちまけないように注意です！！:mask:
③退職できる:blush:
駅すぱあと VBA SDKを使って駅簡易情報を取得する

**本記事はヴァル研究所の支援として作成された記事です**

[駅すぱあとはAPIを公開](https://api-info.ekispert.com/)しており、駅情報や経路探索などをAPI経由で行えます。メソッドはすべてGETメソッドで、情報取得系のみです。レスポンスはJSONまたはXMLで返ってきます。

この駅すぱあと APIを利用しやすくするSDKを開発しはじめました。SDKはVBAで作っており、Excelなどから利用できます（Windowsのみ、macOSでは利用できません）。

今回は、スタンダードプランで提供されている駅簡易情報取得APIに対応したので、その使い方を解説します。

## 必要な情報

SDKを利用する際にはAPIキーが必要です。[無料トライアルがあるので、こちらから取得](https://api-info.ekispert.com/form/trial/)してください。

## 注意点

- SDKはWindowsでのみ動作します
- SDKは非公式です。公式サポートへの問い合わせはご遠慮ください

## ファイルのインポート

[こちらのリポジトリ](https://github.com/EkispertAPIMania/VBA-SDK)にある `*.cls` と `*.bas` ファイルをすべてインポートします。これらは以下のライブラリを含んでいます。

- [VBA-tools/VBA-Dictionary](https://github.com/VBA-tools/VBA-Dictionary)
- [VBA-tools/VBA-Web: VBA-Web](https://github.com/VBA-tools/VBA-Web)
- [VBA-tools/VBA-JSON](https://github.com/VBA-tools/VBA-JSON)

## 初期化

先ほど取得したAPIキーを使ってSDKを初期化します。

```vb
Dim client As Ekispert
Set client = New Ekispert
client.ApiKey = "YOUR_API_KEY"
```

## 駅簡易情報検索条件の設定

駅簡易情報検索は `StationLightQuery` を使います。このオブジェクトを取得し、検索条件を設定します。

```vb
Dim Query As StationLightQuery
Set Query = client.StationLightQuery()
Query.Name = "東京" ' 駅名で検索

' 都道府県を指定する場合（複数可）
Query.PrefectureCode(0) = Tokyo
Query.PrefectureCode(1) = Kanagawa
' 交通種別の指定
Query.TransportType(0) = LocalBus
' コミュニティバスの扱い
Query.CommunityBus = Except
```

検索条件は [駅簡易情報 - 駅すぱあと API Documents 駅データ・経路検索のWebAPI](https://docs.ekispert.com/v1/api/station/light.html) にあるものを指定できます。

## 検索の実行

検索条件を設定したら、検索処理を実行します。結果は `ResultSet` クラスになります。検索がうまくいったかどうかは `ResultSet.Success` の値で判定してください。

```vb
Dim Result As ResultSet
Result = Query.Find()

Debug.Print Result.Success ' True または False
```

### エラーだった場合

もし検索がエラーだった場合は `ResultSet.Error` の中にエラー情報があります（駅すぱあと APIからのエラーの場合）。

```vb
If Not Result.Success Then
		MsgBox Result.Error.Message
		Exit Sub
End If
```

### 成功した場合

処理が成功した場合、 `ResultSet.Points` の中にポイント情報が入っています。各ポイントには `Station` （駅情報） と `Prefecture` （都道府県） プロパティなどがあります。

```vb
Debug.Print Result.Max ' 200（検索結果数）
Debug.Print Result.Points(0).Station.Code ' 22828
Debug.Print Result.Points(0).Prefecture.Name ' 東京都

Dim i As Long

For i = 0 To UBound(Result.Points)
	Debug.Print i & " " & Result.Points(i).Station.Code
Next i
```

## ソースコード

SDKのコードは以下のリポジトリにて公開しています。ライセンスはMIT Licenseです。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK/tree/main)

## まとめ

駅情報の取得は、経路探索の基本になります。まだ経路探索はできませんが、これから徐々に機能を追加していきます。ぜひお試しください。

何か不具合があれば、Issueにて連絡いただければ対応します（macOSでは動かないので注意してください）。

[EkispertAPIMania/VBA-SDK: Excel VBAなどで動作する駅すぱあと VBA SDKです（Windowsのみ）](https://github.com/EkispertAPIMania/VBA-SDK)
【備忘録】GASでGoogleDriveのファイル一覧を取得する

# はじめに

GASでGoogleDriveのファイル一覧を取得する際の備忘録
前提：Webアプリを作成して、デプロイしておく。

https://qiita.com/firesign2023/items/3fd6bfab624568cd2c78

# コード.gs と index.html

~~~JavaScript:コード.gs
function doGet(e) {
  var fileList = getFilesInFolder('*** ここにFolder IDを入力 ***');
  var template = HtmlService.createTemplateFromFile('index');
  template.fileList = fileList;
  return template.evaluate();
}

// Googleドライブ内の特定のフォルダのファイル一覧を取得する関数
function getFilesInFolder(folderId) {
  var folder = DriveApp.getFolderById(folderId);
  var files = folder.getFiles();
  
  var fileList = [];
  
  // フォルダ内の全てのファイルを取得して、配列に追加
  while (files.hasNext()) {
    var file = files.next();
    fileList.push({
      name: file.getName(),
      id: file.getId(),
      url: file.getUrl(),
      lastUpdated: file.getLastUpdated().toLocaleDateString()
    });
  }
  
  return fileList;
}
~~~

~~~HTML:index.html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile('Stylesheet').getContent(); ?>
  </head>
  <body>
    <h1>File List</h1>
    <table>
      <tr>
        <th>File Name</th>
        <th>File ID</th>
        <th>Download URL</th>
        <th>Last Updated</th>
      </tr>
      <? for (var i = 0; i < fileList.length; i++) { ?>
      <tr>
        <td><?= fileList[i].name ?></td>
        <td><?= fileList[i].id ?></td>
        <td><a href="<?= fileList[i].url ?>" target="_blank">Download</a></td>
        <td><?= fileList[i].lastUpdated ?></td>
      </tr>
      <? } ?>
    </table>
  </body>
</html>
~~~

# CSS用のファイルを用意する

~~~HTML:Stylesheet.html
<style>
.result-display {
  margin-left: 15px;
  font-size: 125%;
}

.error {
  color: #FF0000;
}

.hidden {
  display: none;
}

table {
  width: 100%;
  border-collapse: collapse;
}

th, td {
  border: 1px solid #ddd;
  padding: 8px;
  text-align: left;
}

th {
  background-color: #f2f2f2;
}

</style>
~~~

# デプロイ

デプロイして表示すると、以下のようになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343142/7526a852-9f4c-be45-740b-f6f0396791b1.png)
PythonエンジニアがRubyでスクレイピングをしてみた

# はじめに
普段、Pythonでコードを書いていますが、最近Rubyにも興味を持ち始めました。
言語によって同じコードでどのくらい違いがあるのか気になったので、RubyとPythonで`Selenium`を使った同じスクレイピングを行ってみました。
学習のためのアウトプットなので、間違い等あれば指摘していただけると幸いです。

# Rubyのスクレイピング

## 1. パッケージのセットアップ
```shell
gem install selenium-webdriver
```

## 2. コード
```ruby
require 'selenium-webdriver'

options = Selenium::WebDriver::Chrome::Options.new
options.add_argument('--headless')
driver = Selenium::WebDriver.for(:chrome, options: options)

driver.navigate.to 'https://qiita.com'

puts driver.title

elements = driver.find_elements(tag_name: 'a')
elements.each do |element|
  puts element.attribute('href')
end

driver.quit

```


## 3. 実行
```shell
ruby main.rb
```

```shell:出力
>> Qiita
>> https://qiita.com/
>> ....
```

# Pythonのスクレイピング

## 1. パッケージのセットアップ
```shell
pip install selenium
```

## 2. コード
```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By

options = Options()
options.add_argument("--headless")
driver = webdriver.Chrome(options=options)

driver.get("https://qiita.com")

print(driver.title)

elements = driver.find_elements(By.TAG_NAME, "a")
for element in elements:
    print(element.get_attribute("href"))

driver.quit()

```

## 3. 実行
```shell
python main.py
```

```shell:出力
>> Qiita
>> https://qiita.com/
>> ....
```

# コードの比較
![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/403148/d28ac750-9ef1-d05f-dd9f-256440acba2c.png)

# まとめ
PythonとRubyで同じスクレイピングを行ってみました。
コードの書き方には違いがありますが、基本的な部分は似ていると感じました。
RubyはPythonよりもコードが短くなることが多い印象ですが、どちらも使いやすい言語だと感じました。
個人的にはPythonの方が書きやすいと感じましたが、Rubyも使いこなせるようになりたいです。
ChatGPTと一緒にWebサイト制作③ UML編

## UMLを試す

前回の[ChatGPTと一緒にWebサイト制作② ヒアリング編](https://qiita.com/koji-yamauchi/items/e01bb5b59917545a1dea)からの続きです。
次にUMLを作成できるか試してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426622/9b47166e-9c9e-b265-1fb1-41d70402d2b6.png)


### 私の指示

次にメンバー間や顧客との意識合わせのため、UMLでモデリングを進めていきたいと考えています。
今回のWebサイト制作会社のリニューアルプロジェクトでは、WordPressを導入する予定です。

実績やお知らせの管理と、各ページの文言変更などはCMS（WordPress）から行えるようにする想定です。
考えられるユースケース図をPlantUMLで作成してください。

### ChatGPTの回答

WordPressを導入したWebサイトリニューアルプロジェクトにおけるユースケース図をPlantUMLで作成します。ユースケース図では、以下のアクターとユースケースを想定しています。

#### アクター

* 管理者：サイト全体の設定やユーザー管理を行う。
* コンテンツ編集者：実績やお知らせの管理、各ページの文言変更を行う。
* 訪問者：サイトを訪れて情報を閲覧する。

#### ユースケース

* ログイン：ユーザーがシステムにログインする。
* ユーザー管理：管理者がユーザーアカウントの作成・削除・権限変更を行う。
* サイト設定管理：管理者がサイトの全体設定を行う。
* 実績管理：コンテンツ編集者が実績の追加・編集・削除を行う。
* お知らせ管理：コンテンツ編集者がお知らせの追加・編集・削除を行う。
* ページコンテンツ編集：コンテンツ編集者が各ページの文言を変更する。
* サイト閲覧：訪問者がサイトを閲覧する。

#### PlantUMLコード

以下のPlantUMLコードを使用してユースケース図を作成できます。

```
@startuml
actor 管理者 as Admin
actor コンテンツ編集者 as Editor
actor 訪問者 as Visitor

rectangle WordPress {
  Admin -> (ログイン)
  Editor -> (ログイン)

  Admin --> (ユーザー管理)
  Admin --> (サイト設定管理)
  
  Editor --> (実績管理)
  Editor --> (お知らせ管理)
  Editor --> (ページコンテンツ編集)
  
  Visitor --> (サイト閲覧)
}

(ログイン) <|-- (ユーザー管理)
(ログイン) <|-- (サイト設定管理)
(ログイン) <|-- (実績管理)
(ログイン) <|-- (お知らせ管理)
(ログイン) <|-- (ページコンテンツ編集)

@enduml
```

```plantuml
@startuml
actor 管理者 as Admin
actor コンテンツ編集者 as Editor
actor 訪問者 as Visitor

rectangle WordPress {
  Admin -> (ログイン)
  Editor -> (ログイン)

  Admin --> (ユーザー管理)
  Admin --> (サイト設定管理)
  
  Editor --> (実績管理)
  Editor --> (お知らせ管理)
  Editor --> (ページコンテンツ編集)
  
  Visitor --> (サイト閲覧)
}

(ログイン) <|-- (ユーザー管理)
(ログイン) <|-- (サイト設定管理)
(ログイン) <|-- (実績管理)
(ログイン) <|-- (お知らせ管理)
(ログイン) <|-- (ページコンテンツ編集)

@enduml
```

## まとめ

わかりやすいビジュアルの仕上がりではありませんが、いくつかやり取りを重ねると精度があがりそうです。

自力でモデルを書き上げるなら、Draw.ioのほうが思考を止めず手軽に扱えますが、生成AIと一緒にすすめるにはコードとしてシンプルに定義できるPlantUMLのような技術が親和性高そうですね。


## ChatGPTと一緒にWebサイト制作シリーズ

* [ChatGPTと一緒にWebサイト制作① 調査編](https://qiita.com/koji-yamauchi/items/1615a7479d482b899fee)
* [ChatGPTと一緒にWebサイト制作② ヒアリング編](https://qiita.com/koji-yamauchi/items/e01bb5b59917545a1dea)
* [ChatGPTと一緒にWebサイト制作③ UML編](https://qiita.com/koji-yamauchi/items/774d0d7a445ae8562052)
* [ChatGPTと一緒にWebサイト制作④ サイトマップ作成編](https://qiita.com/koji-yamauchi/items/4dd67868dc5b0bf903c3)
AtCoderをC#で始めてみたよ　-AtCoder Beginner Contest 358-

コンテスト的なの参加してみたいけどとりあえず直近の過去問を漁る，前回のやつは[こちら](https://qiita.com/YamayouOmiya/items/e87f665c9e4f1236308e)

https://atcoder.jp/contests/abc358

## [A - Welcome to AtCoder Land](https://atcoder.jp/contests/abc358/tasks/abc358_a)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/6d6e495b-c2ce-b00e-65dd-3bf000b29d80.png)




### コメント

まあ一問目だしね，イージー
```C#
using System;
using System.Linq;
class Program
{

    static void Main(String[] args)
    {
        string[] input = Console.ReadLine().Split(' ');
        string[] str = { "AtCoder", "Land" };

        if (input[0] == str[0] & input[1] == str[1]) Console.WriteLine("Yes");
        else Console.WriteLine("No");
        
    }
}
```
## [B - Ticket Counter](https://atcoder.jp/contests/abc358/tasks/abc358_b)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/95801651-3fd9-9f06-d964-fbc35061ffdb.png)


### コメント
これもわかりやすかった．終了時間だけメモっていってT[i]との時間と比較して条件分岐
```C#
using System;
using System.Linq;
class Program
{

    static void Main(String[] args)
    {
        string[] input = Console.ReadLine().Split(' ');
        int N = int.Parse(input[0]);
        int A = int.Parse(input[1]);

        int[] T = Console.ReadLine().Split(' ').Select(int.Parse).ToArray();
        int finT = 0;

        for(int i = 0; i < N; i++)
        {
            if (T[i] - finT >= 0)
            {
                finT = T[i] + A;
                Console.WriteLine(finT);
            }
            else
            {
                finT += A;
                Console.WriteLine(finT);
            }
        }
    }
}
```

## [C - Popcorn](https://atcoder.jp/contests/abc358/tasks/abc358_c)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3817552/d119e433-c393-db16-afc3-ea43723149e7.png)



### コメント

BからCへの難易度の落差えぐくない？bit全探索で2^Nのパターンを考える．Listが便利だってのいうのを学んだ．

```C#
using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        string[] input = Console.ReadLine().Split(' ');
        // nとmを読み込む
        int n = int.Parse(input[0]);
        int m = int.Parse(input[1]);
        int ans = 20;
        // n行の文字列をリストに読み込む
        List<string> s = new List<string>();
        for (int i = 0; i < n; i++)
        {
            s.Add(Console.ReadLine());
        }

        for(int i = 0; i < (1 << n); i++)
        {
            bool[] exist = new bool[20];
            int count = 0;
            for(int j = 0; j < n; j++)
            {

                if (((i >> j) & 1) == 1)
                {
                    count++;
                    for(int k = 0; k < m; k++)
                    {
                        if (s[j][k] == 'o') exist[k] = true;
                    }
                }
                    

            }

            bool allExist = true;

            for (int j = 0; j < m; j++)
            {
                if (!exist[j])
                {
                    allExist = false;
                    break;
                }
            }

            if (allExist) ans = Math.Min(ans, count);

        }

        Console.WriteLine(ans);
    }
}
```
わたしはここで力尽きた