OmniAICreator/Qiita-1.07M huggingface dataset:
LangchainでYoutubeの内容を要約しようとしたらエラーが起きた

# 事象
AdventCalendarをいい機会としてLangchainのチュートリアルで遊んでいた

https://qiita.com/shin62833/items/3fc5be20f3045a979fae


するとこんなエラーが出てきた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1911348/a441bda9-8a94-034f-a118-69cf8de1be53.png)

[stackoverflowの記事](https://stackoverflow.com/questions/76139725/got-error-in-langchain-youtube-loader-it-says-keyerror-videodetails-pytubeer)によると、古いyoutubeクライアントだとyoutubeに接続できないとのこと。

# 解決策
requirements.txtを見ると、pytube==15.0.0となっているのでとりあえず最新版をインストールしなおしてトライ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1911348/36bd510f-9e4a-bb47-fe3b-ba077ad6ecd4.png)

うまくいったようでよかった
Googleドライブでファイル数上限に達してしまったときの対処

# はじめに
Googleドライブに容量制限があることはみなさんご存知と思いますが、実は（？）ファイル数制限も存在します。
ファイル数上限は2024/12/06時点で50万個であり（[参考：GoogleWorkspaceラーニングセンター](https://support.google.com/a/users/answer/7338880?hl=ja)）、これはそうそう超えることがなさそうに思われるかもしれませんが、定期実行スクリプトでログファイルを出力していたり、何らかの巨大なプロジェクトをそのままアップロードしたりすると、意外と超えてしまう場合もあります。
今回はこのような場合について、その対処を説明します。

# ケース１：原因のフォルダがわかっている場合
たとえば、ローカルに保存していた巨大なプロジェクトをそのままGoogleドライブにアップしてバックアップを試みたりした場合や、大量のログデータをそのままアップロードしてしまった場合など、一撃でこの上限を突破することもあり得ます。
このような場合には原因が明らかなので、対処しやすいです。ただその巨大なファイルを消してしまえば問題ありません。アップロードが不完全なまま停止していることもあり得ますが、ファイル上限に達してしまっている以上アップロードが正常に終了することはないので、一思いに削除してしまいましょう。

# ケース２：原因のフォルダがわからない場合
一方で、原因のフォルダがわからずに上限に達してしまった場合、対処が困難になります。「知らない場所でファイルが急増して上限に達してしまうことなんてあるの？」と思われるかもしれませんが、
たとえば簡単に、毎分実行するスクリプトが毎回エラーログファイルを出力すると、1日で1440ファイル、一年足らずで50万ファイルの上限に達する可能性がありあます。これが、たとえばそれまで正常に動いていたスクリプトが急にエラーになるようになったり、ユーザが気まぐれで作って放置して忘れてしまったりなど、意外と簡単に上限に達することがあり得ます。

このような場合、まず原因のディレクトリを探すことから始める必要があります。
Linuxサーバ等の場合、コマンドによってファイル数の多いディレクトリを探すこともできますが、（[参考リンク](https://qiita.com/kompeki/items/44e7c59045622804a6f8)）残念ながら現時点（2024/12/06）でGoogleドライブにファイル数の配置に関する統計を見る方法は存在しません。

そこで、GASを用いてファイル数を算出します。
### ファイル数算出スクリプト
下記のスクリプトにフォルダーIDを記載して実行してください。
フォルダーIDは、GoogleドライブのフォルダURLの~/folders/以下の部分（下のアスタリスク部分）です。
```
https://drive.google.com/drive/u/0/folders/********ThisIsFolderID*********
```
```JavaScript
function main() {
  var parentFolderId = 'ここにIDを記入する'; // 確認したい親フォルダのIDをここに入力
  var parentFolder = DriveApp.getFolderById(parentFolderId);
  
  // 親フォルダ直下のファイル数をカウント
  var parentFiles = parentFolder.getFiles();
  var parentFileCount = 0;
  while (parentFiles.hasNext()) {
    parentFiles.next();
    parentFileCount++;
  }
  var subfolders = parentFolder.getFolders();

  // 親フォルダ直下のすべてのサブフォルダについて処理
  while (subfolders.hasNext()) {
    var subfolder = subfolders.next();
    console.log("-----------------------------File Opened: "+subfolder.getName()+"-----------------------------");
    var fileCount = countFilesInFolder(subfolder);
    parentFileCount += fileCount;
    Logger.log('-----------------------------Folder: ' + subfolder.getName() + ' - Total number of files: ' + fileCount+"-----------------------------");
  }
  Logger.log('Total number of files in parent folder: ' + parentFileCount);
}

function countFilesInFolder(folder) {
  var files = folder.getFiles();
  var subfolders = folder.getFolders();
  
  var fileCount = 0;

  // フォルダ内のすべてのファイルをカウント
  while (files.hasNext()) {
    files.next();
    fileCount++;
  }

  // フォルダ内のすべてのサブフォルダを再帰的に処理
  while (subfolders.hasNext()) {
    var subfolder = subfolders.next();
    fileCount += countFilesInFolder(subfolder);
  }
  console.log(folder.getName() + ": " +String(fileCount));
  return fileCount;
}
```
#### 注意点
実行には非常に時間がかかります。GoogleWorkspaceユーザの上限実行時間は30分ですが、30分で数万~十数万ファイル程度の計測が関の山です。一般アカウントの6分では~3万ファイル程度が関の山かと思われ、かなり絞った範囲での実行が必要になりそうです。

### 原因のフォルダの削除
原因のフォルダを特定したら、フォルダを削除/退避しましょう。特定のファイルのみを削除したい場合にもGASは便利です。
また、場合によっては自動実行スクリプトが原因となっている可能性もあるので、そのような場合は実行停止やバグ修正など、根本原因を行っていきましょう。

# おわりに
Googleドライブでは、ファイル数上限が意外と厳しい割に、チェックする方法がほとんどありません。自力でスクリプトを作成する等して、地道に原因を探っていきましょう。
【Atcoder】学生灰色コーダーの私がc++のSTLをまとめる。二度と検索しなくていいように。

## はじめに
こんにちは、3週ほど前から本格的にAtCoder Beginner Contestに参加し始めた学生です。

コンテスト中に、「このSTLってどう使うんだっけ？」となり、検索しに行くことが多いので、一度まとめてみようと思い記事を書いています！

一度にいろいろ書くのもパンクしてしまいそうなので、メソッドや、STLコンテナ等は別の記事に書きます！

この記事はあくまでも、「調査してまとめる」という作業による、記憶の定着のためのものですので内容についてはN番煎じのものになっています。間違っている部分があれば指摘していただけると幸いです！


## 最大値・最小値 `max`　`min`
- 最大値・もしくは最小値を返す
```c++
max(a,b);//大きい方を返す
max([a,b,c,d,e]);//一番大きいのを返す
```
## 交換　`swap`
- 二つの変数の値を交換する
- いちいち`tmp`とか準備して交換しなくていいからな！！
```c++
swap(a,b); //aとbの値を交換
```
## 乱数生成 `rand`
- $0～  2 ^ {31} - 1$の乱数を返す
- `1~N`の乱数を生成したい場合は`rand()%N+1`とする
- `srand`によるシード値の指定が必要
```c++
srand((unsigned)time(NULL)); //時刻でシード値を設定

rand()%5+1 //1以上5以下のランダムな整数を返す
```
## 配列,vectorを逆順にする `reverse`
- `.begin()`、`.end()`を使い、イテレータにより指定
- stringにも適用可能
:::note warn
- vectorのa：`a.begin()+l` `a.end()-r`で指定

- 配列：`a+l`,`a-r`で指定
:::
```c++
vector<char> a = { 'a', 'b', 'c', 'd', 'e' };

reverse(a.begin()+1,a.begin()+3);//=>{ 'a', 'd', 'c', 'b', 'e' }
```
## ソート `sort`
- `reverse`と同じ方法で指定した範囲をソートする
- デフォルトは昇順（小さい順）
- 引数にgreater<int>()を追加することで降順(大きい順)にソート可能
```c++
vetor<int> a={5,2,1,4,3};

sort(a.begin(),a.end());//{1,2,3,4,5}
sort(a.begin(),a.end(),greater<int>());//{5,4,3,2,1}
```

## 2分探索　`lower_bound`
- **昇順にソートされている範囲**のイテレータを返す
- を取得できる
- 全探索より圧倒的に早い
- 範囲の指定方法は`reverse`、`sort`と同じ
- 3つ目の引数に探索したい値を指定する
- 最後に`a.begin()`をマイナスすることでインデックスを取得できる
```c++
vector<int> a={5,2,1,4,3}
sort(a.begin(),a.end())

cout << lower_bound(a.begin(),a.end(),4)-a.begin() //=>3
```

## カウント　`count`
- 配列、vectorの指定した範囲中に含まれる、指定した値の数を返す
```c++
vector<char> a ={'a','b','a','c','a'};
cout << count(a.begin(),a.end(),'a');//=>3
```

## 値の存在と場所　`find`
- その値が存在するのか、存在する場合はどこにあるのかを返す
- `reverse`,`sort`,`lower_bound`と同じ方法で範囲を指定できる
- 値が複数ある場合は先頭のイテレータが、含まれない場合は末尾の隣のイテレータが返される
- `lower_bound`と同じで`a.begin()`をマイナスしてインデックスを取得する
```c++
vector<int> a = {4,6,2,15,8};

cout << find(a.begin(),a.end(),15)-a.begin();//=>3
coust << find(a.begin(),a.end(),999999);//=>5
```

## 2進数中の1の数　`__builtin_popcount
- 立ってるビット数を数えてくれる
```c++
int num = 15;
cout << __builtin_popcount(num)//=>4
```

# まとめ
以上になります。もう検索しません！二度と！

`find`や`count`を知らずに今までごり押しでfor文回してたのが恥ずかしいです^^

とりあえず茶色を目指します！！！

# 参考
https://atcoder.jp/contests/apg4b/tasks/APG4b_o

https://qiita.com/e869120/items/518297c6816adb67f9a5
Power Apps：選択された値を基準にした、列のグループ集計

## 序
今年もやってきました、Advent Calendar の季節です。
シリーズ２の日付にまだ空きがある様子だったので、当記事で塞いでしまおう…という記事です。よろしくお願いします。

https://qiita.com/advent-calendar/2024/powerapps

### 実装したい機能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952933/0615673a-f49f-1d08-2262-2f6785d8fcd0.png)

上のテーブルにある「単価」×「注文数」における「合計金額」の集計業務は、レコード単位であれば容易ですが、以下の画像のように、予算番号ごとの「合計金額」を算出したいという場合があると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952933/fb09e82d-ec75-1d3e-21f4-627cfd32f117.png)

また、部署コードごとにそれを算出したい、というご要望も少なからずあると思います。本記事では、Power Apps 上でそういった処理を行いたい時の Tips を紹介します。

### Special Thanks
今回の記事は、益森さんの以下の記事を参考にしてアレンジを加えているものです。基本は、こちらの記事を読んでいただければ理解は早いと思います。

https://qiita.com/Takashi_Masumori/items/4f685db43de4f3b4d309

いつもありがとうございます。今度はそちらへ遊びに行きますね（私事）

### GroupBy関数
https://learn.microsoft.com/ja-jp/power-platform/power-fx/reference/function-groupby

### まずはフィルタリング
まずはテーブル全体から、特定の部署コードでフィルタリングしてコレクション（配列）化する必要があります。特定の部署コードは、動的に変更されることを見越して、ドロップダウンコントロール（drpCode）を配置します。

また、集計処理を実行するためのボタン（btnRun）を配置しておきます。drpCpde でフィルタリングした結果を、コレクションに格納する際の数式は次のとおりです。

~~~
btnRun.OnSelect =
ClearCollect(コレクション名, Filter(データソース名, 部署コード = drpCode.Selected.Value))
~~~

このフィルタリングの際、単価 × 注文数の合計金額も同時に算出していく必要があります。グループ集計の前に手順を踏むことが大事ですね。各レコードに対して計算を仕掛けていくことになりますので、繰り返し処理が必要な場面です。ForAll関数で囲っていきます。

~~~
btnRun.OnSelect = 
ClearCollect(
    コレクション名,
    ForAll(
        Filter(
            データソース名,
            部署コード = drpCode.Selected.Value //フィルタリングしたデータソースに対して
        ),
        //以下、実行される数式
        {
            予算番号: ThisRecord.予算番号,
            科目: ThisRecord.科目,
            合計: 単価 * 注文数
        }
    )
);
~~~

新たに、元のデータソースに存在しない合計金額列をコレクション側で作成しています。そうしてできたコレクション（筆者は colTempSum と名付けました）は次の通りです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952933/343a3ef9-c235-585d-d70b-448ff29b061e.png)

部署コード "79032" でフィルタリングしたテーブルで、まずは各レコードの集計結果を得ることができました。ここから、共通する予算番号を基準にした合計金額を算出してみましょう。

### グループ化して集計する
先ほど集計したテーブルを土台にして、グループ化を行います。上の数式に続けて、以下の数式を書きます。

~~~
ClearCollect(
    colSum,
    ForAll(
        GroupBy(
            colTempSum,
            予算番号, 科目, // 「予算番号」と「科目」でグループ化
            GroupedResults
        ),
        {
            予算番号: ThisRecord.予算番号,
            科目: ThisRecord.科目,
            合計: Sum(GroupedResults, 合計) // グループごとの合計を計算
        }
    )
);
~~~
複雑に感じる式ですが、最初に作成したコレクションを GroupBy関数で囲んでグループ化し、それをデータソースとして計算式を実行している感じです。今回は合計金額の集計なので、Sum関数で集計しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2952933/0e98aad7-7936-2186-bcfc-bfaaa114e693.png)

## 結
GroupBy関数は、便利な半面、普段イメージしているテーブルの構造を脳内で変換していく必要があってとっつきにくさを感じます（親の列に子の列が入っている…みたいなイメージ）

とはいえ、まずは基本のフィルタリングとコレクション作成に集中し、その後でグループ化することで、多少なりともその負担を軽減できると思います。

どの数式を書くにあたっても、基本文法に変化はありません。１つずつ連結することを意識していくと、今後の Power Apps ライフが多少なりとも捗っていくことでしょう（これは常に自分に言い聞かせています。求める結果を焦らない、これ大事）

それでは、また。
Advent of code 2024 Day 5 Part 2 を Livebook で楽しむ

## はじめに

Advent of code 2024 Day 5 の Part 2 を解きます

問題文はこちら

https://adventofcode.com/2024/day/5

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2024/2024_day5_part2.livemd

Part 1 はこちら

https://qiita.com/RyoWakabayashi/private/c61bc9d55b520e010205

## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 5 の入力を取得します

![スクリーンショット 2024-12-06 0.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e16a794e-cd85-e51d-2417-364555ce01f6.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>回答</summary>

入力の読込処理は Part 1 と同じです

Part 2 では誤っている更新について修正する必要があります

誤った更新の探索は Part 1 の逆を実行すればよいだけなので、末尾に `|> then(&(not &1))` をつけるだけです

修正処理では、前後関係が誤っている箇所について、位置を入れ替えます

入れ替えた結果、以前は正しかった前後関係が誤った状態になる可能性があるため、修正した場合は改めて先頭のルールからチェックし直す必要があります

再帰処理が必要なため、モジュール化しました

```elixir
defmodule Fixer do
  def get_wrong_updates(updates, rules) do
    updates
    |> Enum.filter(fn update ->
      rules
      |> Enum.reduce_while(nil, fn {a, b}, _ ->
        a_index = Enum.find_index(update, &(&1 ==a))
        b_index = Enum.find_index(update, &(&1 ==b))

        if is_nil(a_index) or is_nil(b_index) do
          {:cont, true}
        else
          if a_index < b_index do
            {:cont, true}
          else
            {:halt, false}
          end
        end
      end)
      |> then(&(not &1))
    end)
  end

  def fix_update(update, rules) do
    rules
    |> Enum.reduce(update, fn {a, b}, acc_update ->
      a_index = Enum.find_index(acc_update, &(&1 ==a))
      b_index = Enum.find_index(acc_update, &(&1 ==b))

      if is_nil(a_index) or is_nil(b_index) do
        acc_update
      else
        if a_index < b_index do
          acc_update
        else
          acc_update
          |> List.update_at(a_index, fn _ -> b end)
          |> List.update_at(b_index, fn _ -> a end)
          |> fix_update(rules)
        end
      end
    end)
  end
end
```

入力例に対して実行してみます

```elixir
updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
  Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
```

実行結果

```elixir
123
```

問題文と同じ値になりました

実際の入力に対して実行します

```elixir
{rules, updates} = parse_input.(puzzle_input)

updates
|> Fixer.get_wrong_updates(rules)
|> Enum.map(fn update ->
  Fixer.fix_update(update, rules)
end)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
```

</details>

## まとめ

問題文から ChatGPT に画像を生成してもらいました

![aoc2024_day5_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/ff6c4171-c83b-dc5b-afb3-fd94bc27498b.png)

修正処理で再帰的なチェックが必要で、そこで少し躓きました
Advent of code 2024 Day 5 Part 1 を Livebook で楽しむ

## はじめに

Advent of code 2024 Day 5 の Part 1 を解きます

:::note info
Part 2 の変更点が多いので別記事に分割しました
:::

問題文はこちら

https://adventofcode.com/2024/day/5

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2024/2024_day5_part1.livemd

## セットアップ

Kino AOC をインストールします

```elixir
Mix.install([
  {:kino_aoc, "~> 0.1"}
])
```

Kino AOC の使い方はこちらを参照

https://qiita.com/RyoWakabayashi/items/3d3abcf9134cee4dff05

## 入力の取得

"Advent of Code Helper" スマートセルを追加し、 Day 5 の入力を取得します

![スクリーンショット 2024-12-06 0.57.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e16a794e-cd85-e51d-2417-364555ce01f6.png)

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>回答</summary>

入力を読み込むための関数を用意します

```elixir
parse_input = fn input ->
  [rules, updates] =
    input
    |> String.split("\n\n")
    |> Enum.map(&String.split(&1, "\n"))

  rules =
    rules
    |> Enum.map(fn rule ->
      rule
      |> String.split("|")
      |> Enum.map(&String.to_integer(&1))
      |> List.to_tuple()
    end)
  
  updates =
    updates
    |> Enum.map(fn update ->
      update
      |> String.split(",")
      |> Enum.map(&String.to_integer(&1))
    end)
  
  {rules, updates}
end
```

入力例で試してみます

```elixir
{rules, updates} =
  """
  47|53
  97|13
  97|61
  97|47
  75|29
  61|13
  75|53
  29|13
  97|29
  53|29
  61|53
  97|53
  61|29
  47|13
  75|47
  97|75
  47|61
  75|61
  47|29
  75|13
  53|13
  
  75,47,61,53,29
  97,61,53,29,13
  75,29,13
  75,97,47,61,53
  61,13,29
  97,13,75,29,47
  """
  |> String.trim()
  |> parse_input.()
```

実行結果

```elixir
{[
   {47, 53},
   {97, 13},
   {97, 61},
   ...
 ],
 [
   [75, 47, 61, 53, 29],
   [97, 61, 53, 29, 13],
   [75, 29, 13],
   ...
 ]}
```

正しい更新だけを抽出する関数を用意します

各ルールについて、前後の文字両方が存在していて、前後関係が誤っているものがあれば正しくない更新です

```elixir
get_right_updates = fn updates, rules ->
  updates
  |> Enum.filter(fn update ->
    rules
    |> Enum.reduce_while(nil, fn {a, b}, _ ->
      a_index = Enum.find_index(update, &(&1 ==a))
      b_index = Enum.find_index(update, &(&1 ==b))
  
      if is_nil(a_index) or is_nil(b_index) do
        {:cont, true}
      else
        if a_index < b_index do
          {:cont, true}
        else
          {:halt, false}
        end
      end
    end)
  end)
end
```

入力例で実行します

```elixir
updates
|> get_right_updates.(rules)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
```

実行結果

```elixir
143
```

問題文と同じ結果になりました

実際の入力で実行れば答えが出ます

```elixir
{rules, updates} = parse_input.(puzzle_input)

updates
|> get_right_updates.(rules)
|> Enum.map(fn update ->
  Enum.at(update, div(length(update), 2))
end)
|> Enum.sum()
```

</details>

## まとめ

問題文から ChatGPT に画像を生成してもらいました

![aoc2024_day5_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/c5916730-5000-15d4-a8c3-68c240b48cea.png)

単純なチェックだけなので簡単ですね

Part 2 はこちら

https://qiita.com/RyoWakabayashi/private/b578bdf6e96fdfef790b
docker で実行しているプログラムがどんな通信をしているのか監視したい!

## 目的

謎のライブラリやアプリケーションがどんなサーバーと通信しているのか監視したいなぁ...
と思ってそんな環境を作りました。

## システム構成

docker で下記の2つのサービスを立てる

 - squid コンテナ
     - 通信制御用
 - 開発用コンテナ
     - ここでプログラムを実行する

## ファイル構成

下記のようにファイルを配置

```shell
$ tree .
.
├── compose.yml
├── dev
│   └── Dockerfile
└── proxy
    ├── Dockerfile
    ├── squid.conf
    └── whitelist.txt
```

### compose.yaml


```yaml:./compose.yaml
services:
  squid-container:
    build:
      context: .
      dockerfile: ./proxy/Dockerfile
    ports:
      - 3128:3128
    networks:
      - con-network
      - iso-network

  dev-container:
    build:
      context: .
      dockerfile: ./dev/Dockerfile
    networks:
      - iso-network
    tty: true

    environment:
      HTTP_PROXY: http://squid-container:3128
      HTTPS_PROXY: http://squid-container:3128
      http_proxy: http://squid-container:3128
      https_proxy: http://squid-container:3128

networks:
  iso-network:
    name: iso_network
    internal: true

  con-network:
    name: con_network
```

## 開発用 Dockerfile

`apt install` の中身はネットワーク通信の確認用

```Dockerfile:./dev/Dockerfile
FROM mcr.microsoft.com/devcontainers/base:jammy
ENV TZ=JST

RUN apt update
RUN apt upgrade -y
RUN apt install -y curl iproute2 dnsutils
```

## Squid 用 Dockerfile

squid の設定ファイルやホワイトリストはあらかじめコピーする

```Dockerfile:./proxy/Dockerfile
FROM ubuntu/squid
ENV TZ=JST

RUN apt update
RUN apt upgrade -y
RUN apt install -y curl

RUN mkdir /etc/squid/acl

COPY proxy/squid.conf /etc/squid/squid.conf
COPY proxy/whitelist.txt /etc/squid/acl/whitelist.txt
```

### squid.conf

ホワイトリストに記載されたサイトだけを許可し、それ以外の通信は拒否。

```conf:./proxy/squid.conf
http_port 3128

acl whitelist dstdomain "/etc/squid/acl/whitelist.txt"
http_access allow whitelist

http_access deny all
```

### whitelist.txt

ホワイトリストのファイルに通信をしてもいいサイトを記述していきます。
.がはじめについてるとサブドメインを許可。なければそのサイトだけ許可。

```txt:./proxy/whitelist.txt
.google.com
yahoo.com
```


## 実行!

```shell
docker compose up -d
```

### 通信ができるパターン

```shell
$ curl google.com
<HTML><HEAD><meta http-equiv="content-type" content="text/html;charset=utf-8">
<TITLE>301 Moved</TITLE></HEAD><BODY>
<H1>301 Moved</H1>
The document has moved
<A HREF="http://www.google.com/">here</A>.
</BODY></HTML>
```


### 通信ができないパターン



```shell
$ curl www.yahoo.com    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html><head>
<meta type="copyright" content="Copyright (C) 1996-2021 The Squid Software Foundation and contributors">
(以下略)
```

### 通信ログの確認

下記のコマンドを確認すれば、通信状況が確認できます。

```shell
docker logs -f squid-container-1
```

あとは通信を監視したいプログラムを開発コンテナ内で実装をするだけ...かな?
【エラー解決】cannot import name 'runtime_version' from 'google.protobuf'

## 結論
https://github.com/tensorflow/models/issues/11192

ただ少しごちゃついてて見づらいのと、備忘録として。

## 解決手順
### 1. protobufのアップグレード
以下のコマンドを実行して、protobufをアップグレードする。
```bash
pip install --upgrade protobuf
```
次に、`runtime_version.py`を探す。環境にもよるが、以下のパスにある。
```
仮想環境のパス/site-packages/google/protobuf/
```

### 2. runtime_version.pyのバックアップ
見つけた`runtime_version.py`を適当な場所に避難する

### 3. protobufのダウングレード
必要なバージョンにprotobufをダウングレードする。例:
```bash
pip install protobuf==3.19.6
```

### 4. runtime_version.pyを復元
ダウングレード後、`runtime_version.py`が消えているため、先ほど避難させたファイルを元の場所にコピーする。
slコマンドとはなんなのか

皆さん、ターミナルで作業しているときに、ちょっとしたミスで面白いことが起こること、ありますよね？
その一例が、`sl`コマンドです。
実は、`sl`はターミナルにおける「ちょっとした遊び心」みたいなもので、特にUnix系システムでインストールされていたりします。

今日はこの`sl`コマンドについて、ちょっとした小ネタとして紹介。

## `sl`コマンドとは？

まず、`sl`は正式には「Steam Locomotive」の略で、蒸気機関車をターミナルに表示するコマンドなんです。ただし、普通に`sl`を打っても、ターミナルに蒸気機関車が表示されるだけなので、実際には「これ、何の役に立つんだ？」と思うかもしれません。

実は、このコマンドが生まれたきっかけは、`ls`（ディレクトリ内容の表示）コマンドのタイプミスにあります。ターミナルで`ls`と打ちたかったのに、うっかり`sl`とタイプしてしまうことがあるんですよね。その時に、ユーモアを交えて蒸気機関車が画面に表示されるという、ちょっとしたジョークとして`sl`コマンドが作られたんです。

## インストール

Debian:
```bash
apt install sl
sl
```

MacOS:
```bash
brew install sl
sl
```

## バカバカしいコードはいいぞ

こういった微妙に使えないジョークコードは世界にたくさん転がってるので興味があればぜひ調べてみてさいまし。

もう少し先にslコマンド風でサンタが横切るコードを書くのでお楽しみに。
Ant Design X: Craft AI- driven interfaces effortlessly

[中文](https://github.com/ant-design/x/issues/205) | **English**

 ## Introduction

Ant Design X is a brand new AGI component library from Ant Design, designed to help developers more easily develop AI product user interfaces. Building on Ant Design, Ant Design X further expands the design specifications for AI products, offering developers more powerful tools and resources. We look forward to driving the development of AI technology with you!

+ Official Website: [https://x.ant.design](https://x.ant.design)
+ GitHub Repo: [https://github.com/ant-design/x](https://github.com/ant-design/x)
+ npm：[`@ant-design/x`](https://www.npmjs.com/package/@ant-design/x)
+ Design Assets：[RICH - Sketch](https://github.com/ant-design/x/discussions/256)

![HomePage](https://github.com/user-attachments/assets/77baff83-b79b-4c4a-b8e9-c1f2ebb8828a)


![Demos](https://github.com/user-attachments/assets/47f2b3e7-464f-40b2-835f-22d2e7e35be3)

## Design Philosophy
Ant Design X builds a systematic theory and methodology for AI product design— the "RICH Design Paradigm"— to help everyone understand what an AI product interface is and create an excellent AI product experience.

This theory and methodology guide us to focus not only on the tangible interface experience but also on the intangible experience rules. It will lead us through the AI design journey, gradually identifying invisible experience rules such as intent, roles, conversations, and defining hybrid interface forms that integrate various interaction modes like natural language conversation. Want to know more? Visit the [Design Module](https://x.ant.design/docs/spec/introduce) on the official Ant Design X website!

## Rich Components
The design paradigm is split into multiple components, giving developers great flexibility in combination. Additionally, we provide technical tools that make data consumption ready to use out of the box, enabling a single X to accomplish all front-end development work:

<img src="https://github.com/user-attachments/assets/1d59dd9b-0492-4213-ae8d-57be4dabde8a" width="500" />

#### Combinable as Needed

![Chat](https://github.com/user-attachments/assets/b90a2dc9-a45d-4c26-85d0-ad80fb40e636)

## Future Plans
Ant Design X aims to provide a consistent user experience with Ant Design, making it easy to expand and integrate with existing projects. In the future, we will also offer style extensions for mobile design specifications, enabling developers to conduct multi-terminal development simultaneously. Stay tuned.

![Mobile](https://github.com/user-attachments/assets/4c810e81-005e-4e0c-9c33-d0f88a88b7ea)

## In Conclusion
As a community-driven open-source project, Ant Design has greatly benefited from the help of the community. We thank everyone!

We hope that Ant Design X will not only help developers improve work efficiency and reduce the learning curve but also provide consistent and high-quality user experiences through detailed design specifications and a friendly development environment, helping developers tackle various complex design needs with ease.

So, give it a try: [https://x.ant.design/](https://x.ant.design/)
2024-12-06 共有記事ログ

# 概要
現職の開発部のメンバーに共有した記事のログ

# 技術系
## [【責務の分離】複数の関心が入ったルーティングファイルの改善](https://developers.prtimes.jp/2024/11/27/improvement-by-separation-of-concerns/)
関心の分離という点で実際のコードをリファクタリングした流れと視点を示した記事です
Clean Architecture の様に層での考え方も取り入れながら関心の分離を行うと
よりリファクタリングの視点が定まって考えやすくなりそうだというのと
実際のコードが例になっているのでリファクタリングのイメージがしやすそうということで共有します！

## [CodeDeployを利用したときの連続デプロイには罠がある](https://zenn.dev/coconala/articles/e2123bd7c0cfed)
CircleCI と CodeDeploy で Blue Green Deployment の自動化を行っていた場合にハマった内容の記事です
CI の方法はこれに限った話ではありませんが、安全性の向上を主とした冗長化構成としては求める形だと思いましたので
ハマった内容というよりかは作りたい構成を認識してもらいたいので共有します！


# To Intern
## [知ってそうで知らないHTTPS](https://qiita.com/nucomiya/items/f4251cfd3e2ff8fd2612)
HTTP と HTTPS が何かを説明した記事です
基本的なことですが、丁寧に説明されているので一度目を通しておくと、Webの仕組みの理解が進むと思います！


# 共有するほどではないけど興味があったもので読んだもの
* [VimConf 2024へ参加して体感したお気持ち](https://zenn.dev/gmomedia/articles/vimconf2024_kansou)
    * vimのイベントがあるって知らなかったw
* [【エンジニアの日常】エンジニア達の人生を変えた一冊 Part3](https://tech.findy.co.jp/entry/2024/11/25/070000)
    * 2冊目の本は読んだことが無いから結構気になる
* [Webエンジニアなら知っておきたいイベント駆動アーキテクチャ](https://engineers.fenrir-inc.com/entry/2024/11/25/153652)
    * 仕組みとしてはわかるし、どういう概念のものかも理解できるが、これをどう適切に選択するかが難しいなと思った
* [PdM（プロダクトマネージャー）とPM・PjMの役割の違いを基礎から解説](https://product-managers-club.jp/blog/post/basic-explanation-difference-between-pdm-pm-pjm)
    * PdM と PjM の違いがいまいちわからなかったので調べた
    * PdM は製品開発に責任を持ち、PjM は特定のプロジェクトを定め、その中で責任を持つ内容
    * PdM と PjM はどちらが上とかそういった視点はなく、責任範囲が異なるという理解をした
* [セキュリティ運用って包括的にできていますか？SaaSを使って次のステップへ【資料公開】- Classmethod Cloud Security Fes.](https://dev.classmethod.jp/articles/slug-OvSfxCKsWHnf/)
    * Splunk も選択肢としてはありなのかもしれない。DataDog との比較をちゃんとしてみたい
* [AIの女の子がわいわい競馬予想するシステムを個人展示したら倍率2000倍の馬券が当たってしまった (1)設計思想編](https://qiita.com/oktamajun/items/34c2287a9f4d9ac9c298)
    * マルチエージェントLLMオーケストレーション良さげだが、コストやばそうw
* [東大・東大生が公開しているエンジニアが読むべき資料まとめ](https://qiita.com/KNR109/items/853c8d8fe36ede1cc453)
    * 最近これ系の記事が流行っているのかな？似たようなものをよく見かける
* [【最新版】フロントエンドを学べる最高の教材集](https://qiita.com/KNR109/items/528cbcaafb84aa57553d)
    * 自分はフロントエンド弱いから、しっかり読み込む時間を作りたい
* [【常識】知らないと土台に立てないエンジニア就活情報まとめ](https://qiita.com/eureka-ai/items/c455b7451f9aca8211a0)
    * このまとめはありがたい
* [【入門】生成AI関連を学べる資料まとめ](https://qiita.com/KNR109/items/57b680e1eaab4d744d68)
    * 最近はAIネタがめちゃくちゃ多いが、今はまだ何を使うにも金がかかる
* [これだけはできてほしいgitとGitHub](https://qiita.com/tomoswifty/items/be3ff39ab3361a8e9c47)
    * 超初学者向け
* [OCRはもう不要？視覚的特徴とテキストを高精度に捉える！次世代マルチモーダルAIモデル『MPLUG-DOCOWL2』登場！](https://qiita.com/ryosuke_ohori/items/34581692852b8b406139)
    * どんどん新しいモデルが出てきているみたいだけど、使いこなすための環境と勉強が必要になるなと思った
* [AWS CDK に初めて触ろうとしている人に向けて、必要な概念をざっくり解説 & おすすめドキュメントまとめ](https://qiita.com/hosomatu/items/14d4de0888fe91ebd9a)
    * CFnとCDKの比較をちゃんとしたい
* [ハッカソンでDifyを使おう！〜3位を取ったアプリの作り方〜](https://qiita.com/kyuko/items/cb6b38bcc031b7f11563)
    * Difyの料金次第だけど結構良さそう
* [ノーコード×AIで爆速アプリ開発の新時代！リリースまで可能な『Replit Agent』！](https://qiita.com/ryosuke_ohori/items/c40d357bdab6e6cb1c56)
    * 成果物の精度にはとても興味がある
* [【ログ分離】 ログデータを DB に保存してはいけません](https://zenn.dev/primenumber/articles/179cd19b6c9e79)
    * ログについてもガイドラインを固めて、しっかり運用できるように考えていかなければと思う
* [パッケージ管理方法を知る！〜パッケージマネージャーの仕組み編〜](https://note.com/dev_onecareer/n/n47a436e0dda7)
    * 更新情報を毎週確認するのは大事かも
    * 溜まってから更新するのは大変だから
ゲーム開発時の仕様書や仕様作成者との関わり方

# 概要
テンプレートや規約が無い環境では、エンジニアに共有される概要や仕様書は作成者によって内容が変わってくる
機能の一部がまだ仕様未作成だったり、「何が変わるか分からないけど拡張性高く作っといてください」と言われることもある

そんな中でも開発を進めなければいけない
「流石にここは変わらないだろ」と思っている部分に変更が入っても、「今からじゃ時間が足りません:cry:」ということにならないようにしたい

まだ発展途上だが、自分の仕様書や仕様作成者との関わり方, 考え方を書き留めておく

# 仕様書
### 書いてある数字は変わりやすい
「`装備枠は2つ`」「`同じキャラクターが3つ揃ったら進化する`」「`アイテムの最大所持数は4個`」
仕様書にこう書いてあっても油断しない
できる限り変更に柔軟な実装をしておく

事前に対応できないものには、対応にどのぐらい工数がかかるかを自分の中に持っておき、いざ変更要望が来た時に答えられるよう準備しておく

### 画面遷移と表示要素は変わりずらい
「ホーム画面 -> バトル準備画面 -> バトル画面」
といったような画面遷移は変わりにくい
また「ホーム画面ではプレゼントボックスとバトル開始ボタンを表示する」のように、表示する内容は変わりづらい

その代わりデザインは常に変わり続ける

### 値の最大値最小値
全ての数値には最大値と最小値を持たせた方がいい
また、有効桁数や文字列の最大長も決める
例えばキャラクターのレベルや攻撃力、攻撃力倍率など

これが自由すぎると、予期せぬ不具合が発生する
決めるコストと不具合修正のコストを比べた時に、決めるコストが圧倒的に低いので決めておくべき

基本的に最初から記載があることは少ないので、エンジニアから足りていない部分をどんどん提案する

### データの形をそのまま採用しない
時々想定のDBのテーブルまで記載してくれる人がいる
とてもありがたいが、実装との兼ね合いがあるため自分らで再度考え直すこと
ここにこだわりを持っている人とまだ会ったことがないので、変更要望が通りやすい

### 実装されたロジックと仕様書が対応づけられているようにする
仕様書に記載されているロジックの分割で実装されていると、後から入ってきた人やエンジニア以外の人に説明しやすい
また、不具合が発生した際も修正しやすいし、偉い人に話しやすい


# 仕様作成者
### 細かいことも変更されたものもドキュメントへ記載してもらう
口頭やチャットのみで情報伝達を終わらせない
細かいことでも必ずどこかへ記載してもらう

機能実装の際には `仕様書へ記載` -> `実装する` という流れを守る
「先に実装進めちゃって」というのも極力許さない (※もちろん期限優先で)

### 面白さについて話す時には発言に注意
「面白くない」と言うのは最終手段にする
相手も人間で、作ったものにそんなことを言われたくない

「ユーザーの選択幅が少ない」や「プレイ目的を感じにくい」なども同様

もうさっさと自分が面白そうなものを作ってしまうか、「うわーーー、ここにミッションとかあったら絶対面白いんですけどどうですか！？」みたいに無邪気な感じで言っちゃう
面白さについて議論モードに入るのは時間の無駄になることが多いし、結論がふわっとしがち

### 仕様の変更への温度感を伝える
「ここは変えられます」「ここは時間かかります。」とかをどんどん伝える
そのために仕様の変更の話には敏感になっておく

### 運用時のデータ量を聞いておく
ページングは必要？イベントの期間かぶりはある？
ユーザーが所持するアイテムの総定数はどのぐらい？

運用時にどのぐらいのデータが作られるかを確認しておく

### 仲良くなる
これが一番
仕様の方針や運用時の想定など、いっぱい聞き出しちゃおう

# まとめ
開発に楽しくなりすぎない
ビジネスを阻害しないために、仕様をある程度ハンドリングすること
Logseqで新しい知識ネットワークを構築する

:::note info

この記事は[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico) カレンダー4の6日目の記事です。

こちらの記事はカレンダー1の6日目の記事[わからないことを理解するための知識ネットワーク](https://qiita.com/zacky_50/private/6716b0ad12577ed28698
)を具体的にどのように実践しているかについての記事となっています。ぜひこちらも合わせてご覧ください。
:::



# Logseqで知識ネットワークを構築する方法

こんにちは。2024年4月に新卒で入社したばかりの新人エンジニア、@zacky_50です。

今回は、私が知識ネットワークを作るために愛用しているツール「Logseq」についてご紹介します。この記事では、Logseqを使ってどのように効率的な学習や情報整理ができるのか、その具体的な使い方やメリットについて解説します。
知識ネットワークについては冒頭で紹介の[こちらの記事](https://qiita.com/zacky_50/private/6716b0ad12577ed28698)をご覧ください。


## Logseqとは？

https://logseq.com/

**Logseq**は、アウトライナー形式のノートアプリで、双方向リンクや階層構造を活用して情報を整理できるツールです。マークダウン形式でメモを作成でき、ノートやアイデアを簡単にリンクさせることができます。

この特性は、知識ネットワークを構築するのに非常に適しており、個々の概念や用語をつなげていくことで、学びを深めるための土台を作ることができます。



## Logseqで知識ネットワークを構築する方法

### 1. 概念や用語をノードとして記録する

まずは、新しく学ぶ分野やトピックに関連する概念や用語を個別のノードとして新規ページに記録します。例えば、「オブジェクト指向」というページを作り、その中に関連する情報を書き込んでいきます。

![スクリーンショット 2024-12-06 0.32.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784514/fedf3ff1-dcfe-f8c2-70ca-10421fa5f3ec.png)

### 2. 関連性を双方向リンクでつなぐ

記録したページ同士をリンクでつなぎます。例えば、「クラス」というページを作成し、「オブジェクト指向」のページから[[クラス]]と記述することで、それらの関連性を表現できます。

![スクリーンショット 2024-12-06 0.38.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784514/d386342d-c758-92b5-7deb-08c563d02a6a.png)

このようにリンクを活用することで、知識の全体像を視覚的に捉えやすくなります。

### 3. 階層的に情報を整理する

Logseqのアウトライナー形式を使って、情報を階層的に整理します。以下はその一例です：

- **オブジェクト指向**
  - クラス
    - メソッド
    - プロパティ
  - インスタンス
  - 継承

階層構造を活用することで、細かい情報を見逃さずに整理できます。

### 4. グラフビューで全体像を確認する

Logseqの**グラフビュー**機能を使えば、作成した知識ネットワークを視覚的に確認できます。

![スクリーンショット 2024-12-06 0.44.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784514/52e9dd40-ac87-bf0a-0ef1-0451ed1ec1ff.png)

各ノードが他のノードとどのように関連しているかを一目で把握できますし、中心的なノードはその領域の重要なキーワードであることがわかります。（下の図ではクラスにつながるものが多いので、クラスは押さえておきたい重要ワードであると判断できる。）

![スクリーンショット 2024-12-06 0.45.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2784514/ed84098c-ccb2-0dc3-9dcb-815ba030f632.png)


## Logseqを使うメリット

1. **知識の整理が簡単**  
   双方向リンクや階層構造を活用することで、複雑な情報を整理しやすくなります。

2. **全体像の把握が可能**  
   グラフビューで情報のつながりを視覚化できるため、どの部分を優先的に学ぶべきかが明確になります。

3. **検索性が高い**  
   過去に作成したノードやメモにすぐアクセスできるため、必要な情報を効率よく引き出せます。

4. **ローカル保存で安心**  
   Logseqはローカル環境で動作するため、プライバシーを気にせず使用できます。

5. **拡張機能で機能追加が可能**  
   プラグインや拡張機能を導入することで、さらに機能を拡張することができます。たとえばOpenAIのAPIを使って、自動要約や文章生成を行うことも可能です。
   これによってわからないことを即座に情報を整理・理解するのに役立ちます。


## まとめ：Logseqで広がる学びの可能性

Logseqは、学びの効率化や知識ネットワークの構築を支援する便利なツールです。初めて使う際には少し戸惑うこともあるかもしれませんが、基本的な操作に慣れると情報整理がしやすくなり、学習をより体系的に進められるようになるでしょう。

自分に合った使い方を探しながら、ぜひ一度Logseqを試してみてください。使い続けるうちに、自然と知識が広がり、新しい発見や学びにつながるかもしれません。

最後までお読みいただき、ありがとうございました。なにかの参考にしていただければ幸いです。
また[LITALICO Engineers Advent Calendar 2024](https://qiita.com/advent-calendar/2024/litalico)の他の記事もぜひご覧ください！それでは！
Is F# the new Python?

最近、F#を試してみたんだけど、なんか思ったよりも「これ、Pythonに似てない？」って感じた。もちろん、F#はPythonじゃなくて、ちゃんと独自の強みがあるんだけど、Pythonのような手軽さと、あの「すぐに結果が見える感覚」っていうのが、どこか似てる気がする。
だから、今日はその辺についてちょっと語ってみる。「F#ってどうなの？」って気になってる人の参考になれば嬉しい！

## F#って何？

まず、F#は「関数型プログラミング」の言語のひとつ。簡単に言うと、コードがデータの変換に集中してるって感じ。
変数をどんどん変更していくっていうよりも、入力を与えたらそのまま出力を返すみたいな感じ。
だから、だいぶ直感的に書けることが多い。

でも、F#はそれだけじゃなくて、オブジェクト指向や手続き型もサポートしてるから、結構自由に書ける。
だから、「関数型プログラミング＝難しい」みたいな先入観を持ってる人にも意外と入りやすいんじゃないかなと思う。

## Pythonっぽいところ

さて、F#を使ってみて感じた「Pythonっぽい」点だけど、まず「簡単に結果が見れる」っていうのが大きい。
Pythonって、手軽にコーディングしてすぐに実行してみて結果を見ることができるから、初心者でも「うおー、動いた！」って実感できるじゃん？
F#も同じで簡単に触れるっていうのが似てるかも。

F#にもREPL（Read-Eval-Print-Loop）環境があるから、すぐにコードを書いて動かすことができる。
で、ちゃんとエラーメッセージもわかりやすいし、初心者でも「あ、ここ間違ってるんだな」ってすぐにわかる。

あと、Pythonみたいにライブラリが豊富ってわけじゃないけど、F#でも.NETのライブラリを使えるから、結構なんでもできちゃうんだよね。
だから、ちょっとした計算やデータ処理もちょちょいとやってくれる。

## F#がPythonに勝ってる点

Pythonってすごく便利だけど、やっぱり「遅い」っていうのがネック。
特に、大量のデータを扱うような場面では、どうしてもパフォーマンスが気になる。
だけど、F#はコンパイルされる言語だから、Pythonよりも全体的に速い。
これは、パフォーマンスを重視するプロジェクトでは大きなアドバンテージになると思う。

しかも、F#は並列処理も得意なんだよね。複数のタスクを並行して処理する場合、F#の方が得意かもしれない。
Pythonも「asyncio」や「multiprocessing」などのライブラリを使えば並列処理はできるけど、F#ではそれがもっと自然に扱えるように感じた。

## Pythonとの違い

でも、もちろんF#にはPythonにはない特徴もある。
例えば、F#は型安全で、型推論が強力。
それに、関数型プログラミングを活かすための仕組みも色々あって、例えばリストの操作が非常に簡単。Pythonでもリストを使うけど、F#ではもっとパワフルに扱えるように感じた。

あと、F#の文法はPythonに比べるとちょっと厳密だし気をつけないとエラーになっちゃうことがあるから、そこは最初ちょっととっつきにくいかも。
でも、慣れてくると構文なんて些細な問題な気がする。

## 結論：F#はPythonの後継者？

「F#がPythonの後継者か？」っていう質問には、なんともいえないかも。
だって、PythonにはPythonの良さがあるし、F#にはF#の強みがあるから。
でも、もしPythonでちょっとパフォーマンスや並列処理に困ってる人がいれば、F#を試してみる価値は大いにあると思う。

Pythonっぽい書きやすさがあって、かつより速く動かせるっていうのは、かなり魅力的なポイントだよ。
だから、Pythonを使ってるけどちょっと限界を感じてきた人は、F#を検討してみるのもアリだと思う。

結局のところ、F#が「新しいPython」ってわけじゃないけど、Pythonのように簡単に書けるし、しかもいろいろな面で強力な言語だから、使ってみる価値は十分にあるって感じ！
TeXとは何か？私が使って感じたこと

TeX（テフ）は、1978年にドナルド・クヌース教授によって開発された、主に科学技術文書や数学的な表現を記述するための文書作成システムです。
特に数式や学術論文の作成に優れており、プログラミングのようにテキストを入力して美しいレイアウトを自動的に生成してくれるため、専門家の間で広く使用されています。
TeX自体はプログラムであり、ユーザーが記述したソースコードをコンパイルしてPDFなどの出力ファイルを生成します。

## TeXの特徴

TeXの最大の特徴は、数式を含む文書を美しく整形できる点です。
数学記号や数式を簡潔なコードで記述でき、細かなレイアウト調整が可能です。
また、TeXはプログラムとしての性質を持っているため、非常に柔軟で拡張性が高いです。
さまざまなパッケージを利用して、文書のスタイルや機能をカスタマイズすることができます。

さらに、TeXは文字やレイアウトの位置調整を非常に精密に行います。
そのため、印刷物に近い形で高品質な出力を得ることができ、特に出版業界や学術界で重宝されています。

## TeXを使って感じたこと

初めてTeXを使ったとき、最初はその独特な書き方に戸惑いました。
たとえば、数式を記述するためには、`\begin{equation}`や`\end{equation}`など、特定のコマンドを使わなければならず慣れませんでした。
しかし、数式をきれいに表現できることや、フォントやレイアウトの自由度はOffice系のソフトの追随を許さないレベルで感動しました。

TeXは特に、長い数式や複雑な数式を扱う際に便利です。
Officeなどでは、数式の整形が難しく、見栄えもよくないことが多いですが、TeXではコードを少し書くだけで美しい数式を表示できます。
また、文献管理や参照、索引作成も自動で行えるため、論文を書く際には非常に効率的です。

一方で、かなり敷居が高いようにも感じました。
環境構築の手間や独自の記述が多く使われている分、とっつきにくさが感じられました。

## 結論

TeXは、特に数学や科学技術に関する文書作成において、非常に優れたツールです。
美しいレイアウトと高品質な数式表現を実現できるため、学術論文や書籍の執筆において欠かせない存在となっています。
その高い学習コストと引き換えに美しい文章作成があるとすれば納得かなと思います。
商用環境でEFSバックアップするときは顧客要件を確認しよう

# チェックを入れるだけでバックアップを有効化できてしまう
- Amazon EFSの自動バックアップ設定は構築時にチェックをいれるだけで簡単に有効化できてしまう
- バックアップ処理はAWS Backupというサービスが行っている

# AWS Backupはどのタイミングでバックアップを行っているのか？
- バックアッププランを見ると以下のようになっている
  - バックアップ頻度：毎日 5:00（AM UTC）から8時間以内に開始
  - バックアップ期限：7日以内に完了
  - ライフサイクル（バックアップの保存期限）：5週間後に失効(35日間)
  - バックアップ方法：増分バックアップ

# その自動バックアップ設定で要件を満たせますか？
- EFSを用いて検証環境を作る場合はこれでいいかもしれないが、商用サービスとして運営するなら安易に自動バックアップを有効化して終わりではなく、必要な設定の洗い出しが必要になる
- 特にバックアップ中はEFS内のファイル参照は可能
- 一方、書き込みや削除等、ファイルに変更を加える処理は不整合が生じる可能性ありとAWSドキュメントにも記載されている※「バックアップの整合性」を参照
https://docs.aws.amazon.com/ja_jp/efs/latest/ug/awsbackup.html

- ストレージ容量やシステム利用ピーク時間、書き込み等の有無などシステム特性や顧客要件を考慮しつつ、必要なバックアップ方法をとる必要がある
[Flutter] TextFieldのキーボードをデフォルトで日本語キーボードに設定する

# 現状

日本語入力したいのに英語キーボードが表示される。
日本語キーボードに切り替える手間があるので、デフォルトで日本語キーボードにしたい。

<img width=320 src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/3583df26-0f05-baad-0a0c-db95b003253b.png'>

# 手順

## flutter_localizations をインストール

pubspec.yaml に以下を追加
```yaml
dependencies:
  flutter_localizations:
    sdk: flutter
```

追加した状態で以下を実行
```zsh
flutter pub get
```

## main.dart を修正する

main.dartの `MaterialApp` 内に以下を追加する
```dart
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:flutter/cupertino.dart';

MaterialApp(
  supportedLocales: const [Locale('ja', 'JP')],
  localizationsDelegates: const [
    GlobalMaterialLocalizations.delegate,
    GlobalWidgetsLocalizations.delegate,
    GlobalCupertinoLocalizations.delegate,
    DefaultCupertinoLocalizations.delegate,
  ],
  ..省略..
)
```

# hot reload して動作確認

デフォルトで日本語キーボードが表示されるようになった🎉
<img width=320 src='https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3900714/3d22dd57-24e0-52b4-3faa-ae346aa5765e.png' />
evergreen を使って Dependabot の作成、設定漏れがないか確認する


## はじめに

github/evergreen は対象の Organization または repository に 依存package の更新が実行可能であるにもかかわらず `.github/dependabot.yml` が存在しない場合に Issue または Pull request を作成してくれる Action です。

github/evergreen を設定することで、 Dependabot の設定漏れを表面化しプロジェクトが脆弱性にさらされたり、安定性が損なわれたり、全体的なパフォーマンスが低下したり等あらゆるリスクを低減できると考えられます。

## evergreen を設定する

README.md の通り evergreen を設定すればOKです。

設定する repository は Organization (や ユーザー) が保持する任意の repository で構いません。
ただし、`ORGANIZATION` env に ユーザー名 (渡しの場合は `mziyut`) を設定しても正しく動作しません。 Organization を設定するようにしてください。

個人が保持する repository に対して evergreen を設定したい場合は、 `mziyut/foobar` 等のように repository path を指定してください。

```yml:.github/workflows/dependabot-checks.yml
name: Weekly dependabot checks

on:
  workflow_dispatch:
  schedule:
    - cron: '0 0 * * 6'

permissions:
  contents: read

jobs:
  evergreen:
    name: evergreen
    runs-on: ubuntu-latest
    permissions:
      issues: write

    steps:
      - name: Run evergreen action
        uses: github/evergreen@v1.15.3
        env:
          GH_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
          REPOSITORY: mziyut/disposable-email-domains-js
```

## Ref

https://github.com/github/evergreen

https://github.blog/security/supply-chain-security/do-you-know-if-all-your-repositories-have-up-to-date-dependencies/

https://github.com/mziyut/mziyut/blob/master/.github/workflows/dependabot-checks.yml
ABC381

2024/11/22にABC381が開催されました。いつものように挑んだのですが、まさかの０完！
今回のABCはwhileループを使用する問題で構成されていました。
敗因は私がwhileループを理解していなかったから。
復習と反省を兼ねてA,B,C問題の回答をpythonで書きました。
```python:ABC381A
N = int(input())
s = list(input())
isYes = True
if N%2 == 0:
  isYes = False
else:
  for i in range(N//2):
    if s[i]=='1' and s[-(1+i)]=='2':
      continue
    isYes = False
  if s[N//2]!='/':
    isYes = False
if isYes:
  print('Yes')
else:
  print('No')
```
```python:ABC381B
s = list(input())
isYes = True
if len(s)%2!=0:
  isYes = False
else:
  for i in range((len(s)//2)):
    if s[2*i] == s[2*i+1] and s.count(s[i]) == 2:
      continue
    isYes = False
if isYes:
  print('Yes')
else:
  print('No')
```
```python:ABC381C
N=int(input())
s=input()
answer = 0
for i in range(N):
  if s[i] == '/':
    n = 1
    now1 = i
    now2 = i
    while True:
      now1 -= 1
      now2 += 1
      if now1 < 0 or now2 > N - 1:
        break
      if s[now1] != "1" or s[now2] != "2":
        break
    now1 += 1
    now2 -= 1
    answer = max(answer,now2 - now1 + 1)
print(answer)
```
ABC198 Dの解法メモ【Ruby】

入水目指して過去挑戦して解けてないAtCoder Problems上でDifficultyが水色の問題を解いていく。

# [ABC198 D: Send More Money](https://atcoder.jp/contests/abc198/tasks/abc198_d)概要

3つの英小文字からなる文字列$ S1, S2, S3 $に対して、アルファベットと0~9の数字を1対1対応させたときに、 $ S1 + S2 = S3 $となるような対応を見つけて$ S1, S2, S3 $を数値に変換したものを出力する問題。

# 解法イメージ

まず、数値とアルファベットを対応させるので、アルファベットの種類が11種類以上になると数値を割り当てられない文字が出てくる。
そのため、アルファベットの種類数は10種類以下とする。

10種類の文字に対しての数値の割り当て方は $ 10! = 3,628,800 $通りなので全探査しても間に合う…らしいのだが、実装が下手でTLEしちゃったので1の位から順に文字に数値を当てはめて計算していく。

$ S1, S2, S3 $の右から$ i $番目の文字をそれぞれ$ c1, c2, c3 $だったとすると、$c1, c2$の数値が決まると$ c3 $も自動的に決まるので検討する組み合わせを減らすことができる。
また、すでに数字が割り当てられている文字や残っている数字の組み合わせでは$ c1 + c2 \equiv c3 \pmod{10} $が成り立たなくなった時点で計算を中断できる。

これらによって計算量を減らすことで間に合わせることができる。

# 実装例

```ruby
@s1 = gets.chomp.reverse
@s2 = gets.chomp.reverse
@s3 = gets.chomp.reverse
@arr = (@s1.chars + @s2.chars + @s3.chars).uniq


@max = [@s1.length, @s2.length, @s3.length].max
if @arr.length > 10 || @s3.length < @max
  puts "UNSOLVABLE"
  return
end

def calc(i, u, hash, arr)
  if i == @max
    return if u > 0

    res1 = @s1.reverse.each_char.map {|c| hash[c] }.join("")
    res2 = @s2.reverse.each_char.map {|c| hash[c] }.join("")
    res3 = @s3.reverse.each_char.map {|c| hash[c] }.join("")
    return if res1[0] == "0" || res2[0] == "0" || res3[0] == "0"
    puts [res1, res2, res3]
    exit
  end
  
  c1 = @s1[i].to_s
  c2 = @s2[i].to_s
  c3 = @s3[i].to_s

  m1 = hash[c1]
  r1 = m1.nil? ? 0..9 : m1..m1
    r1.each do |num1|
    if m1.nil?
      next if !arr[num1].nil?
      hash[c1] = num1
      arr[num1] = c1
    end
    
    m2 = hash[c2]
    r2 = m2.nil? ? 0..9 : m2..m2
    r2.each do |num2|
      if m2.nil?
        next if !arr[num2].nil?
        hash[c2] = num2
        arr[num2] = c2
      end

      m3 = hash[c3]
      num3 = (num1 + num2 + u) % 10
      div3 = (num1 + num2 + u) / 10
      if !m3.nil?
        calc(i + 1, div3, hash, arr) if num3 == m3
      elsif arr[num3].nil?
        hash[c3] = num3
        arr[num3] = c3

        calc(i + 1, div3, hash, arr)
        
        hash[c3] = nil
        arr[num3] = nil
      end
      if m2.nil?
        hash[c2] = nil
        arr[num2] = nil
      end
    end
    
    if m1.nil?
      hash[c1] = nil
      arr[num1] = nil
    end
  end
end

calc(0, 0, { "" => 0 }, [])
puts "UNSOLVABLE"
```
エラーPG::UndefinedTable: ERROR:  relation "xxxx" does not exist (PG::UndefinedTable)

## エラー詳細
GitHubでMerge後、renderにて自動デプロイ失敗

```render:deproy logs
Caused by:
PG::UndefinedTable: ERROR:  relation "xxxx(テーブル名）" does not exist (PG::UndefinedTable)
 （省略）
 ==> Build failed
 ```

 ローカルでは問題なく動いてた。
 "xxxx"テーブル関係が存在しないとのことなので心当たりを探っていく

 ## 原因
 色々試したけど、結果マイグレーションファイルのup順が原因でした。

```terminal:ターミナル
  % rails db:migrate:status
```
マイグレーションのステータスを確認
```terminal:ターミナル
database: APP_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20241113021323  Devise create users
   up     20241119002039  Create vvvv
   up     20241119011527  Create wwww
   up     20241129062819  Create yyyy
   up     20241205063125  Create xxxx
````
このYYYYテーブルにxxxxの外部キー書いてたから起きたエラーでした。
順番通り読まれてYが「Xが見当たらないよ！」ってことかな。
<br>
<br>

```ruby:20241129062819_create_YYYY.rb
class Createyyyy < ActiveRecord::Migration[7.0]
  def change
    create_table :yyyy do |t|
      t.string     :phone, null: false
      t.references :xxxx,  null: false, foreign_key: true
      t.timestamps
    end
  end
end
```

原因がわかったのでマイグレーションファイルの順番を変えて行きます。

## 対処法
#### 1.マイグレーション一覧を確認
```terminal:ターミナル
 % rails db:migrate:status


 database: APP_development

 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20241113021323  Devise create users
   up     20241119002039  Create vvvv
   up     20241119011527  Create wwww
   up     20241129062819  Create yyyy
   up     20241205063125  Create xxxx
```
<br>

#### 2.yyyyテーブルを削除する
yyyyテーブルを削除するためにStatusをdownする。
```terminal:ターミナル
rails db:migrate:down VERSION = Migration ID
```
再度ステータスを確認してdownになってたら削除コマンド
### その前に！
順番だけ変えたいのであって中身は変えないのでファイルの内容コピーしてメモに貼っておきます!
<br>
```terminal:ターミナル/削除コマンド
% rm -rf db/migrate/削除したいファイル名　（今回なら20241129062819_create_yyyy)
```
ステータス確認してテーブルが消えていればOK
<br>

#### 3.yyyyテーブルを作り直す
```terminal:ターミナル
%rails g migration create_yyyy
```
でマイグレーションファイルを作りなおして、メモにコピーしていた前述の内容を貼り付け、
Statusをupにすれば出来上がりです
````terminal:Statusをupにする
%rails db:migrate
````

<br>
念のためここでもステータスを確認。
これで無事デプロイできました！


### 余談
マイグレーションファイルの順番で関係あるんですね...
多分ファイル作る時気付けるかもしれないんだけど、
今回の外部キー制約は抜け漏れてて、一度rollbackして足したから
作る時点で気づけなかったんだろうなぁ。

初心者なんで、もっとこうしたほうが〜とかあったらぜひ教えていただきたいです。
よろしくお願いします。
転職にも個人開発が有用だった話

こんにちは。
株式会社dottでエンジニアをしているHALと申します。

dottには2021年５月から働いており、その前の会社はSIerでした。
2020年の夏頃〜転職活動をしていたときの話を書こうと思います。

なお、主に個人開発と転職活動の関係について書くため、転職の経緯については書きません。
現職に転職した経緯については、過去に記事にしていますので、興味があればそちらをご覧ください。

https://qiita.com/hareruya-maro/items/89c7d71fcb10b9ee450e

# 2019年〜個人開発の開始
自分は2019年からReact Nativeで開発したスマートフォンアプリをリリースしています。
現在までに10個ほどのアプリをリリースし、転職活動を始める頃には、既に３〜４個のアプリをリリースしている状態でした。

個人開発を始めた動機としては、もっと開発がしたい、というものでした。
前職のSIer時代もエンジニア職でしたが、社歴が10年になっていたため、リーダー職の比重のほうが重くなり、なかなか開発に割く時間も取れない状態が続いていました。
そこで、自分が普段困っていることをアプリで解決すれば、一石二鳥になるじゃないか、と思いたち、スマホアプリの開発を開始しました。

結果的に、個人開発をすればするほど「もっと開発したい」という思いが強くなり、それが転職の動機にも繋がっていきます。

# 転職活動の開始と個人開発のアピール

転職活動を開始するに当たり、始めはいわゆる転職エージェントを利用しました。
経歴書を添削してもらったり、求人の情報や応募のサポートをしてもらったわけですが、その中でポートフォリオの作成を勧められました。

当然、自分の場合は個人開発で作ったアプリを載せれば良いわけで、以下のような内容を記載しました。

* アプリの概要
* 使用技術
* 開発の背景
* マネタイズについて

内容として興味を持ってもらえるかどうかは、その会社さんの業務内容によって異なりましたが、比較的好印象を持ってもらえたように思いました。

# 個人開発の何が良いか

なぜ個人開発の内容が好印象を持ってもらえたのでしょうか？
理由はいくつかあると思っています。

* 転職のためだけに作ったポートフォリオとは違い、リアルな実力がわかる
* 一人でリリース・運用まで経験していることが証明できる
* 会社の業務の詳細は話せないが個人開発なら詳細まで話せるので細かいことまでわかる

エンジニアの転職では、技術力はやはりひとつの重要なポイントになります。
しかし、業務の内容については、会社の機密事項なども含まれてきますので、だいたいザックリとした本人からの言葉しか聞くことができません。
その点、個人開発については、実際に動いているものを見ることができますし、細かい話まで聞き出すことができます。

また、転職活動向けにポートフォリオとしてサイトを作るようなこともあると思いますが、突貫で作ったものと違い、改善や運用をしているものになるため、より参考にしやすいという面があると思います。
（もちろん、ポートフォリオサイトがだめだということではなく、長く運用しているサイト・アプリの方が有利という話）

そして何より、個人開発はすべて一人でやっているということですので、「自走可能なエンジニアである」ことのこの上ない証明になっていると思います。
どうしても、それができないエンジニアも世の中にはたくさんいますから、自走できるエンジニアがほしいという企業にとっては、好評価の対象となるでしょう。

# まとめ

**個人開発は転職活動にも有利だからみんなもやろう！**
Ubuntuでhadolintを使用する

# 概要
hadolintを使おうと思ったが、ubuntuでやる方法が見当たらずに少し手間取ったのでメモ
macやwindowsではコマンドでインストールできるが、Linux系OSではバイナリファイルをダウンロードすることになる

# 動作環境・バージョン
### 動作環境
Ubuntu : 22.04

# コンテンツ
[公式のリリースページ](https://github.com/hadolint/hadolint/releases/tag/v2.12.0)から、バイナリファイルをダウンロードし、適当な場所に配置。
`chmod +x /path/to/hadolint`で実行権限を付与する

hadolintのVScodeの拡張機能`exiasr.hadolint`をインストール
設定のHadolintPathにインストールしたパスを指定

# 参考文献
[stackoverflow](https://stackoverflow.com/questions/62369711/how-to-install-hadolint-on-ubuntu)
[hadlint公式](https://github.com/hadolint/hadolint)
C#でデザインパターンのシングルトンを学んでみる / Learn singleton design patterns in C#.(日本語 / ENGLISH)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1812041/f296ae90-0e85-479c-a0d3-b6cbcee5775b.png)

# 日本語
こんばんは！
Advent Calendar 2024の6日目投稿をしていきます。
今回はC#についての記事で、シングルトンというデザインパターンについて投稿していきます！

### シングルトンとは
シングルトン（Singleton）パターンは、特定のクラスのインスタンスがアプリケーション全体でただ1つだけであることを保証し、その唯一のインスタンスにアクセスする方法を提供します。

このパターンは、グローバルな設定、ログ記録、キャッシュ管理など、状態を1つだけ管理したい場合に役立ちます。

#### 目的
特定のクラスに1つのインスタンスだけを許容し、全体で共有できるようにする。
#### 利点
インスタンスの重複作成を防ぐ。
状態を一元管理できる。

### 実装例

```c#
public sealed class LazySingleton
{
    private static readonly Lazy<LazySingleton> _instance =
        new Lazy<LazySingleton>(() => new LazySingleton());

    public static LazySingleton Instance => _instance.Value;

    private LazySingleton()
    {
        Console.WriteLine("Lazy Singleton instance created.");
    }
}

//使用例
class Program
{
    static void Main(string[] args)
    {
        LazySingleton instance1 = LazySingleton.Instance;
        LazySingleton instance2 = LazySingleton.Instance;

        Console.WriteLine(ReferenceEquals(instance1, instance2)); // 出力: True
    }
}
```

上のコードは最初のインスタンス呼び出し時のみ、「"Lazy Singleton instance created."」を出力し、2回目の読み出し時は、インスタンスが使いまわされているのコンストラクタは使用されず、「"Lazy Singleton instance created."」は出力されない仕組みになっています。

グローバル的なクラスと考えていいでしょう！
とても面白いですね♪

ここまで読んでいただきありがとうございます！

# ENGLISH
Good evening!
I will be posting day 6 of the Advent Calendar 2024.
This time, I will be posting about C# and a design pattern called Singleton!

### What is Singleton?
The Singleton pattern ensures that there is only one instance of a particular class in the entire application and provides a way to access that sole instance.

This pattern is useful for global configuration, logging, cache management, and other situations where you want to manage only one piece of state.

#### Purpose
Allow only one instance of a particular class to be shared across the board.
#### Advantages
Prevents duplicate instance creation.
Centralized management of status is possible.

### Implementation example

```c#
public sealed class LazySingleton
{
    private static readonly Lazy<LazySingleton> _instance =
        new Lazy<LazySingleton>(() => new LazySingleton());

    public static LazySingleton Instance => _instance.Value;

    private LazySingleton()
    {
        Console.WriteLine("Lazy Singleton instance created.");
    }
}

//example
class Program
{
    static void Main(string[] args)
    {
        LazySingleton instance1 = LazySingleton.Instance;
        LazySingleton instance2 = LazySingleton.Instance;

        Console.WriteLine(ReferenceEquals(instance1, instance2)); // 出力: True
    }
}
```
The above code outputs “”Lazy Singleton instance created.“” only at the first instance invocation, and at the second read, the constructor is not used because the instance is used repeatedly, and “”Lazy Singleton instance created.

You can think of it as a global class!
Very interesting... ♪

Thank you for reading this far!
【SQL初心者向け】まずは覚えるべき5つの基本構文

SQLについて学んでいるのでアウトプットします。
SQLとはなんぞやということと絶対に抑えておきたい5つの構文を紹介します。
# SQLとは
SQLとはそもそも「Structured Query Language」の略です。
SQLを使うことでデータベース（DB）の情報を操作することが出来ます。

# 覚えておきたい5つの構文
### 1. SELECT（データの取得）
SQLの中では最も有名なのではないでしょうか？
`` SELECT ``構文を用いることでDBから必要なデータを取得することが出来ます。

```sql: 例
SELECT column1, column2
FROM table_name
WHERE condition;
```
**ポイント**
* カラム指定：`` SELECT * ``は全ての列を取得するが、必要な情報だけを取得するのが基本
* WHERE句：条件を指定することで必要なデータのみを取得することが出来る

### 2. INSERT（データの挿入）
`` INSERT ``を使用することでデータベース上のテーブルにデータを追加します。
`` INSERT ``ではなくて、`` INSERT INTO ``なので注意してください！
```sql: 例
INSERT INTO table_name (column1, column2)  
VALUES ('value1', 'value2');
```
**ポイント**
* 指定したカラムの順番に値を列挙する

### 3. UPDATE（データの更新）
`` UPDATE ``で既存のDB上のデータを更新することが出来ます。
```sql: 例
UPDATE table_name  
SET column1 = 'new_value'  
WHERE condition;
```
**ポイント**
* SET句：更新するカラムと新しい値を指定する
* WHERE句：条件を指定しないとすべての行が`` UPDATE ``される

### 4. DELETE（データの削除）
`` DELETE ``でDB上のデータを更新することが出来ます。
```sql: 例
DELETE FROM table_name  
WHERE condition;
```
**ポイント**
* `` DELETE``されるのはデータであってテーブルではない
* WHERE句：条件を指定しないとすべての行が``DELETE``される

### 4. CREATE TABLE（テーブルの作成）
`` CREATE TABLE ``でDB上に新しいテーブルを作成します。
```sql: 例
CREATE TABLE table_name (  
    column1 datatype,  
    column2 datatype,  
    column3 datatype  
);
```
**ポイント**
* カラム定義: 各カラムの名前とデータ型を指定する

# まとめ
改めて今回紹介した5つの基本構文をまとめます。
* SELECT：データの取得
* INSERT：データの挿入
* UPDATE：データの更新
* DELETE：データの削除
* CREATE TABLE：テーブルの追加

この5つの基本構文はSQLを初めての案件で使っていく中でマストな構文だったので紹介してみました。
是非、覚えてください！
今回は以上です。