OmniAICreator/Qiita-1.07M huggingface dataset:
Leetcodeを毎日解くという自己研鑽

Waffle College一期生のくるみと申します！

私は、11月に **（ほぼ）毎日Leetcode**に取り組みました。この記事では、なぜLeetcodeに毎日取り組んだのか、どうやって習慣化したのか、成果として得られたものについて、書きたいと思います。

Leetcode Submissionの草。2024年11月**だけ**異常に解いている：

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/245ac869-49c7-9acc-eb84-2c16ab59ebb8.png)

:::note
[1] **Waffle College**は、NPO法人Waffleが運営する、全国の性自認が女性およびノンバイナリーの大学生・大学院生のためのテックキャリアを目指すコミュニティです。
:::

:::note
[2] **Leetcode**は、アルゴリズムやデータ構造の問題を解けるオンラインプラットフォームです。主にコーディング面接対策にも活用されています。
:::

前提として、このチャレンジを始める前の私のレベルは、Easyと簡単めのMediumなら自力で解けるけれど、**難しめのMedium～Hardは解説を見ないと解けない**ことが多かったです。

# なぜLeetcodeを毎日やろうと思ったのか
1. **外資系企業面接（coding interview）のため**
1. **新しい言語の練習のため**

私は11月前半にコーディング面接の予定がありました！面接ために、重い腰を上げ、2年前にたくさん練習したLeetcodeをもう一度頑張ってみることにしました。

練習の結果、**面接ではEasy～Mediumレベルの問題一問を解くことができました**。しかし、もう一つフォローアップとして出された**Hardレベルの問題は、時間内に実装を終わらせることができませんでした**。良い解法は思いついたものの、実装をする時間がなく、残念ながらあと一歩が足りませんでした。私は、そんな自分にやや悔しさを覚えました。（それでも面接は通過したのですが）

そこで私は、面接後もLeetcodeを続けることで、**いつか次の機会で発揮できるスキル**を身に着けたいと思うようになったのです！これが、11月いっぱい毎日Leetcodeチャレンジを続けようと思ったきっかけです。

もう一つの理由は、新しい言語Kotlinの習得です。応募していた仕事はKotlinを使うポジションでしたので、Leetcodeを解きながら楽しく学びたいと思いました。

# Leetcodeを習慣化するために
**毎日同じことに取り組む、というのは想像以上に難しかったです。** やる気があるときは集中できますが、そもそもLeetcodeをやらないといけないということを忘れてしまったり、やらないとだと思っていてもやる気が出なかったりします。

毎日同じことを忘れずに、やる気をもって取り組むにはどうすればいいのか考えたのですが、**手帳を活用してみる**ことにしました。毎日Leetcodeに取り組んだかどうかを、ガントチャート形式のページで可視化しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/0a6e553a-6d4c-413c-c261-5b6ab53ceab2.png)
（取り組んだらチェック✅️してます。てか、ぜんぜん空白がたくさんあるｗｗ）

そもそも、私にとって手帳は馴染みのあるものではありませんでした。最近書き始めたばかりです。そのため、私のようなスマホ大好きデジタル人間が、ちゃんと手帳を使えるのかは疑問でした（笑）。しかし、意外なことに、**毎晩このちいさな四角にチェックマークを書き込むのは楽しい**し、チェックがいっぱいのページを眺めるのも好きです。習慣化において可視化をすることの重要性を実感しました！

## 心理的ハードルを下げるために

また、毎日取り組むために、**心理的ハードルを下げる**ことも意識しました。具体的には、帰宅後疲れているときには、まずEasy問題に取り組むようにしました。そこからやる気が出ればMedium, Hardをやればいいです。

## 一ヶ月Leetcodeチャレンジの成果
Leetcodeに取り組み続けた結果、以下のような成果を得られました。
-  **難しめのMedium問題も自力で解けるようになった**

以前は、難しめのMediumは解法すら思いつかないことがほとんどでした。しかし、毎日取り組む中で、適切なデータ構造とアルゴリズムを用いて解法を思いつく力が向上し、**Medium, ときどきHardでも解法を思いつき、実装まで終えられることが増えました**:sunny:

- **Kotlinという新しい言語を習得できた**

初めはPythonで解いていましたが、先に述べた理由で途中からKotlinで挑戦するようにしました。現在までに17問をKotlinで解いています！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2258874/eb4d7e14-3533-1c4b-229a-ff69d74340da.png)


新たな言語でLeetcodeに取り組むことで、**「あの文法なんだっけ？」となる場面は減りましたし、データ構造の表現方法、idiomaticな書き方も学べました**。さらに、便利なライブラリについて学べて良いです。例えば、今日は**StringBuilder()** の存在を知りました！Pythonにはこういうライブラリ、ないと思う。（リストを使って似たようなことができるけど）

## まとめ
11月のLeetcodeチャレンジを通じて、コーディングスキルの向上だけでなく、新しい言語であるKotlinを学ぶ貴重な機会となりました！また、習慣化の工夫や心理的ハードルを下げる工夫を実践し、**ルーティンを毎日続けることの実践**にもなりました。**12月もこのチャレンジは続けるし、2025年も続けたいと思います**:sunny:

明日のWaffleアドベントカレンダーも楽しみ！
Google apps scriptで作る予実管理システム

企業様より依頼いただいてスプレッドシートを利用した予実管理システムを構築しました。

## 使用技術
Google apps script

## 前提課題
- スタッフ毎の施術予約をスプレッドシート利用により管理していた
- 予約管理ファイルは店舗ごとにシートが分かれており、行には時間情報、列は日付情報が記載されており、各シートの下部数行を用いて、その日毎の実績は関数計算で出力されるようになっていた
- 予約については複数のメニューが存在し、わかりやすくするため「顧客名＋施術メニュー」を記載したセルと、その時間に応じて色をつけていた（スタッフの手動管理）
- 月末締でその月の実績に応じて報酬の支払いが行われていた
- スタッフ毎の予約実績については社員数名が一週間程度かけて目視で実績の整合性を確認し、スプレッドシートで請求書や明細書に反映していた
- 目視での確認は時間と手間がかかりすぎ、ミスも多いので何とかして効率化させたかった

## 求めるもの
- 毎月の実績管理〜請求書の管理までを自動化させたい
- 予約管理自体はスプレッドシートを継続利用し、さらに言えば予約取得方法などUIに関わる部分はなるべく変えたくない
- 予約管理については施術メニューを入力したら色が自動で塗られるようにしたい
- 時折メニュー外にある項目を現金やカードで支払いいただくことがあり、その金額も含めた1日の売り上げ実績を見られるようにしたい
- スプレッドシートで管理している施設以外に、Googleカレンダーで予約を管理している施設もあるので、そちらからも同様に実績を取得できるようにしたい


## 構築していく中で大変だったこと
- スタッフ毎の施術報酬が異なる（経験年数等による違い）
- スタッフ毎で行く施設が異なる
- スプレッドシートで管理している施設において、営業曜日や営業時間が異なる


こういった中でどこまでを処理としてまとめて、どこまでを個別にプログラミングしていくのか、関数利用だけでなくクラスの利用も含めた方が楽になるのかといった考えを持って進めました。

## 作成したもの
### スタッフ・施設をまとめた基本情報が掲載されたスプレッドシートファイル
https://qiita.com/kuma_radcof/items/c5255d310e3277a97143

### 予約管理ファイル（こちらは年毎に管理できるように作成）
https://qiita.com/kuma_radcof/items/d216d3ded9953ed3df47

### 実績管理ファイル

https://qiita.com/kuma_radcof/items/e4b2f58d76b18faa9791
### 請求書・明細書管理ファイル
→こちらについては現状、実績の取得が煩雑かしている関係で要修正な状況。
スタッフ毎、施設毎、店舗ごとの実績がうまく纏まれば自動化の最終段階を修正できる。
ここの自動化まで済むとほぼノータッチで実行可能になる。

### 作成したものをスタッフ毎個別に確認できる管理用ファイル
→こちらはスプレッドシートを個別に作成し、アクセス権限を分けることと、実績データをimportrange関数で閲覧専用にしてみせることで入力状況と、実際の実績取得状況の誤差をなくすことにつながっている。

上記を作成して、それぞれにGASを組んでトリガーにしています。

## プログラム全体の考え方
- 起動時に実行すべき処理、編集時に実行すべき処理、それ以外の定期実行すべき処理を分ける
- 月や年が変わったとしてもアップデート処理が最小限で済むようにプログラムを組む
- 特にGoogleカレンダーでは編集があると変更履歴が取れないので、毎日ログを取れるようにプログラムを組む

## まとめ
Google apps scriptとスプレッドシートを活用すれば予約・実績・請求書発行までの業務を自動化できます。
さらにGoogleカレンダーとの連携や、情報が確定したらPDF処理の追加といったこともできるようにな理ます。
GASの良いところは環境構築の手間がいらないところ、ブラウザ上で動かすことができるところだと思っているのでプログラミング初学者こそGASに取り組んでいって欲しいです。
行頭・行末に文字列を追加するツール(codepen)

## 使い方
基本的には見たまんまです。
行頭行末の空白を取り除きたい場合は「空白削除」→「追加」の流れです。

<p class="codepen" data-height="500" data-default-tab="result" data-slug-hash="MYgaYvz" data-pen-title="行頭・行末に文字列を追加する" data-user="8787kazuye" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/8787kazuye/pen/MYgaYvz">
  行頭・行末に文字列を追加する</a> by ken1math (<a href="https://codepen.io/8787kazuye">@8787kazuye</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 作り方
ほとんどchatGPTにかいてもらってほんの少し微調整です。ほんの数分でできました。
「codepen用にして」とお願いしていますが、いらない部分もかいてくるんですよね。

ざっくり指示をしたあとに、後から思いついたことを足していっています。
見た目もいい感じにしてくれて満足です。

最後に、今回の私の指示を載せておきます。

---

>行頭・行間に任意の文字列を追加するアプリをCodePenを用いて作りたい。
>以下の要件を満たすようなHTML,CSS,JavaScriptをそれぞれかいてほしい。
>
>・変更を加えたい文章を入れるテキストボックス
>・行頭に加える文章を入れるテキストボックス
>・行末に加える文章を入れるテキストボックス
>・「追加」ボタン、「コピー」ボタン
>
>流れ
>・それぞれのテキストボックスに入力する
>・「追加」ボタンをおして行頭行末に文章を追加
>・「コピー」ボタンでテキストボックスの中身をコピー

>行頭と行末の空白を取り除くボタンもほしい

>テキストボックスをクリックしたときに文章全体が選択されるようにしたい

>空の行には追加しないようにしたい
Linux基礎（備忘）

# コマンド
※この記事は、備忘が主目的です。詳細については既存の記事を検索することをおすすめします。
##### ls（ディレクトリ一覧を表示する）
・よく使うオプションでの使用コマンド
ls -lh
　　一覧見るときでサイズを見やすくする
ls -la
　　隠し（ドット）ファイルも確認できる
・オプションじゃないけど備忘
　リストは、名前順で表示される

##### chmod（権限変更）
ファイルの権限を変更する
シェルスクリプトを作成したあととかに実行可能にするときに使う
chmod 777 ファイル名
　777　全権限
　755　ルート以外書き込み不可（シェルとかに使う）

##### vi（テキストエディタを開く）
テキストを編集するコマンドなので、シェルスクリプトの編集とかに使う
vi ファイル名
　ファイル名のファイルでテキストエディタを開く。存在してなければ新規作成
・テキストエディタでのコマンド
:w 保存
:wq 保存して終了
:q! 保存しないで終了
n 前方向で検索
N 後方向で検索
dd カーソル行の削除
i カーソルの左にテキスト追加（インサート）

##### tail（ファイルの最後から数行表示）
・ログファイルの監視に使う
tail -f ファイル名
ログファイルに追記があると表示されるので、プログラムの監視に使える

##### crontab（クーロンの確認修正）
crontab -l
クーロンの表示
crontab -e
クーロンの修正
修正はviと同じテキストエディタが開く

##### history（コマンドの履歴を確認）
history
日時表示の永続化はほか記事を検索
【JS】論理的思考力up＋コードをたくさん書く＝JSでゲームをたくさんつくるが最高だった

## はじめに
なぜブラウザでJSゲームをつくるかというと、

1. 実行環境がブラウザだけで良いこと、
1. すぐに手元で動かして直せるからです


いちばんてっとり早く **「アプリを自分でつくりきる体験」** ができることも利点だと考えています。JSの基本文法がある程度書けるようになったら以下を実施して、プログラマに欠かせない要素である論理的思考力を鍛えましょう！ :muscle: 

たくさんJSゲームをつくるとコードをたくさん書けるので、タイピング速度も上がっていき、一石二鳥です。

https://qiita.com/uekkie/items/7296816045f8a66fcc9b



## やりかた
いたってシンプルですが、

1. 要件を満たすプログラムを書いてもらう
1. ペアレビューしながらロジックを説明してもらう

です。

まずはMVPを決めて、要件を満たすプログラムを書いてもらいます。
以下は、カウンターアプリのコード例。
```Counter.js
const plus = document.createElement("button");
const minus = document.createElement("button");
const reset = document.createElement("button");

plus.innerHTML = "+";
minus.innerHTML = "-";
reset.innerHTML = "Reset";

plus.addEventListener("click", () => {
  if (counter < 9) {
    counter++;
    number.innerText = counter;
  } else {
    console.log("おしまい");
  }
});

minus.addEventListener("click", () => {
  if (counter > 0) {
    counter--;
    number.innerText = counter;
  } else {
    console.log("おしまい");
  }
});

reset.addEventListener("click", () => {
  counter = 0;
  number.innerText = counter;
});

let counter = 0;
const app = document.querySelector("#app");
const number = document.createElement("div");

number.innerText = counter;

app.appendChild(number);
app.appendChild(plus);
app.appendChild(minus);
app.appendChild(reset);
````

次にペアレビューをおこないます。
1行目からコードの説明してもらい説明がおわったらレビュアーは気になる部分について質問していきます。
ロジックについての説明があいまいだった点は本人も理解が完全にできていない可能性があるので、その部分の確認をしてもよいです。

このアクティビティの目的は、論理的思考力を働かせながらプログラムを書けているか？を知ることです。

- :cry: 要件通りに動かない、説明できない
- :thinking: 要件通りに動くが、コードをすべて説明できない
- :smile: 要件通りに動き、コードをすべて説明ができる
- :laughing: 要件通りに動き、コードをすべて説明ができる、（＋α）

＋αの部分に入る観点
- DRYなコード
- リーダブルなコード
- 冗長なものがない短いコード
- 変更しやすいコード


## その他のゲームアプリのバリエーション

実際に作ってもらったJSゲームの種類は以下です。

1. カウンター
1. バルーンゲーム
1. カウントダウンタイマー
1. クイズ
1. 占い
1. ビンゴゲーム
1. TODOアプリ
1. パスワードジェネレータ
1. カレンダー
1. スネークゲーム
1. ブロック崩し


お題は、ほとんどドットインストールを参考にしていますが、いまだとChatGPTにお題のアプリの要件を考えてもらうアプローチもあるかもしれません。

https://dotinstall.com/lessons

## 慣れてきたら

アプリを作ってはプルリクを投げてもらって、ビシバシとレビューをしていきます。最初だからといって手加減をせずに「すべての行にコメントする」くらいの気構えで行きましょう。

はじめの頃はレビューがたくさんついて大変ですが、論理的思考力が伸びてくるにつれ良いコードが書けている実感が持てだすので大丈夫。

実際このカリキュラムのなかで、GitHubでのプルリク→コメント→フィードバック対応のサイクルが100周くらいできるのでGitコマンドやGitHubでの開発が染み付いてくるという副次的効果もありました。
Clojureの基本構文 - 特殊フォームその１

![advent_calendar_2024.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2985550/f4cd8ce0-6352-a1d8-4cae-f39dd44f4def.png)

[*Advent Calendar 2024 Day 5*](https://qiita.com/advent-calendar/2024/clojure)

## 基本構文

3つの基本についてまとめています

1. リテラル
1. 関数の定義と呼び出し
1. 特殊フォーム
今日は **3. 特殊フォーム** のなかの `def` についてまとめます
### 2. 特殊フォーム

特殊フォーム（Special forms）は、Clojureコンパイラによって直接解釈されます

#### def

`def`はシンボルの名前を持ち、現在の名前空間(ns)を名前空間とする、グローバルなvarを作成、登録します

:::note
`var` は値を参照するためのオブジェクトで、変数のようなものです。
変更可能性や、スレッドセーフ性といった性質があります
:::

`:private`や、`:doc`などのシンボルをメタデータとして付与し、特定の挙動を持たせることができます

**:private**

アクセス制御を表し、キーが存在しない場合はpublicになります

```clojure
(def ^:private secret-value "password")
```

**:doc**

varの内容に関するドキュメントを含む文字列(1~3行)

```clojure
(def ^{:doc "この値は今日の夕飯を表します"} dinner "カツ丼")
```

**:test**

`assert`を使用してテストを実行する

```clojure
(def ^{:test (fn [] (assert (= "とんかつ" lunch)))} lunch "とんかつ")
```

ここでは `lunch` の値が `とんかつ`であることを確認しています

**:tag**

定義されたシンボルが返す値の型情報を指定することができる

```clojure
(def ^{:tag String} greeting "Hello, world!")
```

***:file**

シンボルがどのファイルで定義されているか設定します
(指定することはない)

```
clj꞉todo.core꞉> (meta #'breakfast)
{:tag java.lang.String,
 :line 32,
 :column 1,
 :file "/.../clojure-todo/src/todo/core.clj",
 :name breakfast,
 :ns #namespace[todo.core]}
```

**:line**

シンボルが定義された行番号
(指定することはない)

```
clj꞉todo.core꞉> (meta #'breakfast)
{:tag java.lang.String,
 :line 32,
 :column 1,
 :file "/.../clojure-todo/src/todo/core.clj",
 :name breakfast,
 :ns #namespace[todo.core]}
```

**:name**

定義されたシンボルの名前


```
clj꞉todo.core꞉> (meta #'breakfast)
{:tag java.lang.String,
 :line 32,
 :column 1,
 :file "/.../clojure-todo/src/todo/core.clj",
 :name breakfast,
 :ns #namespace[todo.core]}
```

**:ns**

シンボルが属している名前空間


```
clj꞉todo.core꞉> (meta #'breakfast)
{:tag java.lang.String,
 :line 32,
 :column 1,
 :file "/.../clojure-todo/src/todo/core.clj",
 :name breakfast,
 :ns #namespace[todo.core]}
```

**:macro**

このシンボルがマクロであるときにtrueが入る


```
clj꞉todo.core꞉> (meta #'macro-func)
{:arglists ([x]),
 :line 38,
 :column 1,
 :file "/.../clojure-todo/src/todo/core.clj",
 :name macro,
 :ns #namespace[todo.core],
 :macro true}
```

**:arglists**

関数やマクロの引数リストを記録している

```
clj꞉todo.core꞉> (defn greeting [x] (println (str "Hello, " x)))
clj꞉todo.core꞉> (meta #'greeting)
{:arglists ([x]),
 :line 40,
 :column 1,
 :file "/Users/ooka/dev/study/clojure-todo/src/todo/core.clj",
 :name greeting,
 :ns #namespace[todo.core]}
```

明日は他の特殊フォームをまとめようと思います


https://clojure.org/reference/special_forms
リップルのレギュラーキーについて詳しい方教えて下さい。

リップルのレギュラーキーを設定してあるのですが、送金や売買がしたいのですができなくなっています。どうもレギュラーキーが悪さしてるみたいで、よくわからなくなって困っています。解除したくて誰か教えていただける方いませんか？当方素人です。
returnとifの併用方法！

未経験エンジニア転職を目指しているりんころです！
なんじゃこれと思ったので記事にしました！


# returnとifの併用について
```ruby
  def clean?(room)
    return nil if room.blank?
  end
```

これってなんぞやって思ったんですけど、

##### ⭐️簡潔にいうと、if以降のコード「if room.blank?」がtrueの場合、nilを返しますよっていう意味です！ 

例えば、return以降に、コードがあった場合、nilが返されたら、

return以降は実行しないようにする際も使えます！

### 参考サイト
https://qiita.com/hrt_dev/items/3e98ba496bcf8c50ac64
SetとMapを利用したアルゴリズム


### アルゴリズムの概要
このアルゴリズムは、文字列内の各文字の頻度を計算し、頻度が重複している場合に調整を行い、全ての頻度がユニーク（他と重ならない）になるようにするものです。その際、調整に必要な操作回数を最小化し、その結果を返します。

---

### アルゴリズムの詳細
#### **ステップ1: 各文字の頻度を計算**
- 入力された文字列を1文字ずつ走査し、`HashMap`を使用して各文字の出現回数をカウントします。
- 例えば、文字列 `"aaabbbcc"` の場合、`HashMap` は次のようになります:
  ```
  {'a': 3, 'b': 3, 'c': 2}
  ```

#### **ステップ2: 重複する頻度を調整**
- `HashSet` を使用して、すでに使用された頻度（ユニークな値）を管理します。
- 各文字の頻度がすでに `HashSet` に存在している場合、その頻度を1ずつ減らしていきます。
  - この減少処理は、頻度が0になるか、新しい頻度がユニークになるまで続きます。
  - 調整が必要な場合、操作回数をカウントして `answer` に加算します。

#### **ステップ3: 調整後の頻度を記録**
- 調整後の頻度がユニークである場合、`HashSet` に追加します。

---

### 実行例
```java
solution("aaabbbcc")
```
1. **頻度計算**:  
   ```
   {'a': 3, 'b': 3, 'c': 2}
   ```

2. **頻度の調整**:  
   - 'a' の頻度 3 → `HashSet` に追加: `{3}`
   - 'b' の頻度 3 → 重複しているため 2 に減少 → `{3, 2}`
   - 'c' の頻度 2 → 重複しているため 1 に減少 → `{3, 2, 1}`

3. **結果**:  
   調整回数は 2（'b' と 'c' を調整したため）。

---

### 時間計算量と空間計算量
- **時間計算量**:  
  - 文字列を1回走査するため \(O(n)\)。
  - 各頻度調整にかかる最大回数は頻度の値（最大で \(n\)）に依存するため、最悪の場合 \(O(n^2)\)。
- **空間計算量**:  
  - 使用されるデータ構造は `HashMap` と `HashSet` のみで、最悪でも \(O(n)\)。

---

### このアルゴリズムの特徴
1. **効率的な文字頻度計算**:  
   `HashMap` を用いることで、頻度の計算が効率的に行えます。
   
2. **ユニークな頻度の管理**:  
   `HashSet` を使い、頻度が重複しているかどうかを簡単に確認できます。

3. **頻度の調整**:  
   必要最低限の調整操作を行い、結果的に効率的な解法を実現しています。

---

### 改良されたコード（参考）
以下のようにコードを簡略化し、読みやすく改善しました。

```java
import java.util.*;

class Solution {
    public int solution(String s) {
        int answer = 0;
        HashMap<Character, Integer> map = new HashMap<>();
        HashSet<Integer> usedFrequencies = new HashSet<>();

        for (char c : s.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }

        for (Map.Entry<Character, Integer> entry : map.entrySet()) {
            int frequency = entry.getValue();

            while (frequency > 0 && usedFrequencies.contains(frequency)) {
                frequency--;
                answer++;
            }

            if (frequency > 0) {
                usedFrequencies.add(frequency);
            }
        }

        return answer;
    }
}
```

---

このアルゴリズムは、文字列の頻度調整というユニークな課題に対し、効率的でわかりやすい解法を提供しています。
[Go]今さらクロージャキャプチャ問題 & GOTOOLCHAINについて少しだけ

:::note info
この記事は[ZOZO AdventCalender 2024](https://qiita.com/advent-calendar/2024/zozo)シリーズ5の7日目の記事です。
:::

# はじめに
今年の2月にリリースされたGo 1.22でGo言語で長らく問題とされていたクロージャキャプチャ問題が修正されました。  
Go 1.22のリリースからだいぶ時間も経っていて、Go 1.23もリリースされた今、旬を過ぎた話題ではありますが1.21以下のバージョンで実装していて、ちょうどこの問題を踏んだので、改めてGo言語のクロージャキャプチャ問題についてまとめてみます。  
また去年のAdventCalenderでは複数バージョンのGo言語をインストールする方法について書きましたが、Go1.21から導入されているGOTOOLCHAINを使うことで、複数バージョンのGo言語をインストールする必要がなくなりました。  
そのことについても簡単に触れていきます。

# Go言語のクロージャキャプチャ問題
Go言語のクロージャキャプチャ問題は、[FAQにも掲載](https://go.dev/doc/faq#closures_and_goroutines)されるぐらい有名な問題です。  
FAQにも掲載されている通り、1.22で修正されているので最新バージョンのGo言語を使用する分には意識しなくても問題ありません。

## Go言語のクロージャ
Go言語におけるクロージャは、関数リテラルを使って実装します。  
参考: [公式ドキュメント](https://go.dev/ref/spec#Function_literals)
```go
func main() {
    x := 10
    f := func() {
        fmt.Println(x)
    }
    f()
}
```

## 改めてクロージャキャプチャ問題とは
クロージャキャプチャ問題は、クロージャが外部変数をキャプチャする際に、その変数がループ変数の場合に発生します。  
以下の例を見てみましょう。
```go:main.go
func main() {
    var fs []func()
    for i := 0; i < 3; i++ {
        fs = append(fs, func() {
            fmt.Println(i)
        })
    }
    for _, f := range fs {
        f()
    }
}
```
Goのバージョン1.21.x以下でこのコードを実行すると、以下のような出力が得られます。
```bash
 $ GOTOOLCHAIN=1.21.9 go run main.go
3
3
3
 $
```
この出力が得られる理由は、クロージャが変数`i`をキャプチャする際に、`i`がループ変数であるためです。  
クロージャは、外部変数を参照する際に、その変数の値をコピーするのではなく、参照するため、`i`の値が変わると、クロージャから参照される`i`の値も変わります。  
そのため、`i`の値が最終的に`3`になると、クロージャから参照される`i`の値も`3`になります。  
これが、Go言語のクロージャキャプチャ問題です。

## 1.22での修正
1.22ではforループの実装が修正され、ループ変数が繰り返しごとのスコープを持つようになりました。  
参考: 
- https://go.dev/blog/go1.22
- https://go.dev/blog/loopvar-preview

そのため、上記のコードを1.22以降で実行すると、以下のような出力が得られ問題が解消されていることが確認できます。
```bash
 $ GOTOOLCHAIN=1.22.0 go run main.go
0
1
2
 $
```

# GOTOOLCHAIN
クロージャキャプチャ問題の実行例で`GOTOOLCHAIN`という環境変数を使っています。  
Go 1.21から導入された`GOTOOLCHAIN`は、Go言語のツールチェーンを管理するための環境変数です。  
`GOTOOLCHAIN`を使うことで、複数バージョンのGo言語を事前にインストールする必要がなくなりました。  
[公式ドキュメント](https://go.dev/doc/toolchain)  

## GOTOOLCHAINの使い方
GOTOOLCHAIN は以下の形式で設定します
```
GOTOOLCHAIN=[<バージョン>|<バージョン>+auto|<バージョン>+path:<パス>]
```
デフォルト値は`auto`です。  
また`auto`は、`local+auto`の短縮形です。同様に`path`は`local+path`の短縮形です。  
`GOTOOLCHAIN`に`local`と指定すると、常にローカル環境にインストールされているGoを使用します。  
そして`+auto`（または短縮形の`auto`）が設定されている場合、必要に応じて新しいバージョンのGoを選択して実行します。  
具体的には、ワークスペースのgo.workファイルや、go.modファイルに記載されているGoのバージョンを使用します。  
`GOTOOLCHAIN`導入前まではあまり意味を持たなかったgo.modファイルの`go`ディレクティブが、`GOTOOLCHAIN`導入により意味を持つようになり、プロジェクトのGoバージョンを指定する際にも使えるようになったのも便利な点です。  
`GOTOOLCHAIN=1.22`と指定すると、Go 1.22を使用します。  
実行しようとしているGoのバージョンが、まだダウンロードされていない場合、自動的にダウンロードされてキャッシュされます。

## 設定方法
GOTOOLCHAINの設定は以下の優先順で行われます。
1. 環境変数`GOTOOLCHAIN`
2. `go env`による設定
3. `$GOROOT/go.env`による設定

`$GOROOT/go.env`ファイルが存在しないか、他の方法で設定されていない場合はGoコマンドは`GOTOOLCHAIN=local`が設定されているものとして動作します。

# まとめ
- Go言語のクロージャキャプチャ問題についてまとめました。  
- Go 1.22以降であれば問題ないですが、1.21以下のバージョンで実装している場合は注意が必要です。  
- また、Go 1.21から導入されたGOTOOLCHAINを使うことで、複数バージョンのGo言語をインストールする必要がなくなりました。以前のバージョンでの動作を確認するのも簡単になりました。
React学びメモ

【useStateの学び】
【1】useStateはconst[count, setCount] = useState(0)みたいにセットする
【2】setCount(count + 1)とかやると　setCountの値が1になる
【3】setCount(第2引数)をいじって、count(第1引数)の表示を変える。　countは読み専

【evaluateを使わず、リストで電卓を再現する方法】
【1】空のリストをuseStateを使って作る
【2】数値や記号のボタンが押されるたび、リストに格納
【3】while文を使って*や/から優先的に計算→計算した数字をリストに格納し再計算

【neverが出たくだり】
リストを作ったとき、第一引数にneverと出た。
neverは値を入れることができないらしい。
解決方法は、変数作成時に「<b>型を明示しておくこと</b>」
※const [expression, setExpression] = useState<(string | number)[]>([]);

【spliceはリストをいじれる】
let fruits = ["apple", "orange", "banana", "cherry"]
fruits.splice(1, 2);
console.log(fruits)  =>>  [apple, cherry]  みたいになる
勿論追加、置き換えなどもできるみたいだがまた今度

自分メモでした
旧式ATOMでMessaging APIの動作テストしてみた

# 概要

https://qiita.com/jksoft/items/4d57a9282a56c38d0a9c

を参考に手持ちのM5 ATOMで確かめようとしたが、旧式のATOMだったのでそのままでは動かなかったので、スケッチを旧M5 ATOM用に修正した。

ほとんど内容が同じなのでオリジナリティは薄いものの、検索すると新旧の情報が錯綜していてわかりづからかったのもあり備忘録として記事にする。

# スケッチ

```arduino
#define CHANNEL_ACCSESS_TOKEN "チャネルアクセストークン"

// 旧ATOM用のヘッダ
#include "M5Atom.h"
#include <WiFi.h>
#include <HTTPClient.h>

const char* ssid = "Wi-FiのSSID";
const char* password = "Wi-Fiのパスワード";
const char* authorization ="Bearer " CHANNEL_ACCSESS_TOKEN;

// LINE Messaging API ブロードキャストメッセージで通知
void notify(char* message) {
  HTTPClient http;
  http.begin("https://api.line.me/v2/bot/message/broadcast");
  http.addHeader("Content-Type", "application/json");
  http.addHeader("authorization", authorization);
  char body[256];
  sprintf(body,"{\"messages\":[{\"type\": \"text\",\"text\":\"%s\"}]}",message);
  http.POST(body);
  Serial.println(http.getString());
  http.end();
}

void setup() {
  // M5ATOM 用の初期設定
  M5.begin(true, false, true);
  delay(10);
  // シリアルポート設定
  Serial.begin(115200);
  // Wi-Fi接続
  Serial.print("WiFi connecting.");
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }

}

void loop() {
  // ボタンが押されているか判断
  M5.update();
  // 0番（左上隅）のLEDを青に光らせる
  M5.dis.drawpix(0, 0x0000ff);
  // ボタンが押された
  if(M5.Btn.wasPressed()) {
    // 0番（左上隅）のLEDを赤に光らせる
    M5.dis.drawpix(0, 0x00ff00);
    // ボタンが押されたことを通知
    notify("ボタンを押しました！");
  }
  delay(100);
}
```

オリジナルに対してヘッダの変更等に加えて、通知が目に見えないと寂しいと思い、待機状態では青色に、ボタンを押したら赤色に光るようにした。

光らせるボタンはいずれも0番にしているので、旧式ATOM LITEでも動くと思うが未確認。

# 【追記】実際の動画

https://youtube.com/shorts/rcj9W2qmtaY?feature=share
電話番号っぽいけど絶対に存在しないダミーの電話番号がほしい

# 前提
Webサイトで電話番号を使ったテストをするときに、でたらめな数値だとバリデーションに弾かれるけど、実際に存在する値だと、SMSが飛んじゃったりしたら困るというときに、絶対に安心なそれっぽい電話番号が欲しくなることないですか？？
僕はあります！

## 0900で始まる11桁の数字は安全
いきなり結論ですが、0900から始まる11桁の数字は安全と思われます（違ったら指摘ください）

## 安全な理由
まず電話番号は総務省が管理しています。

[総務省 | 電気通信番号指定状況](https://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/number_shitei.html)

上記サイトによると、2024年11月1日時点では、090から始まる電話番号は音声伝送携帯電話番号にしか割り振られていません。

さらにサイトに深く潜っていくとこんなページが
[総務省 | 電気通信番号制度](https://www.soumu.go.jp/main_sosiki/joho_tsusin/top/tel_number/index.html)

こちらの表の利用者設備識別番号 > 音声伝送携帯電話番号の項目を確認すると、携帯電話には以下のようなルールが割り振られているようです。（アルファベットになっているところは変数）

```text
070CDEFGHJK
080CDEFGHJK
090CDEFGHJK
（Cは0を除く）
```

Cは0を除くとのことなので、0900にすれば割り振りルール的に存在しないけどそれっぽい電話番号が作れそうですね！

ちなみにその理論だと0800と0700も当てはまりそうなのですが、0800はフリーダイヤルで存在しているため、脳死でやるにはちょっと危険。調べるのもの面倒なので特段理由がなければ0900を使うのが良さそう。

0700でもいいと思いますがあまり使っている人がいない電話番号なのでちょっとモヤモヤします。あと、なんだかウィルコム2台持ちしてた人がいた時代を思い出します。

## 将来的には？
ちなみにこちら将来的に安全かどうかは怪しいところなので、定期的なチェックは必要と思われますが、そこまで大々的に変わることはないような気がしています。

## 固定電話の場合は？

固定電話の場合も割り振られる範囲が決まっているらしいので、総務省の割り振りを確認して探すと安全にそれっぽい電話番号が作れそうです。

## 良いダミー電話番号ライフを
これでテストデータを作るときに、モヤモヤせずにテストデータを作れますね。

もし、この内容が参考になった方はいいねしてもらえると今後のアウトプットの活力になりますので何卒よろしくお願いしますm(_ _)m
Ruby on RailsにおいてのMVCモデル

この記事は東京海洋大学NePPの Advent Calendar 2024の3日目です。

## はじめに
この記事は、自身がRuby on RailsにてMVCモデルについて学んだことと＋αをアウトプットの機会としてを書きました。
あくまで個人的な見解ですので、あしからずご容赦ください。

## MVCモデルとは？
まずMVCってなんだよってところからですが、
MVCモデルは、ソフトウェアの設計パターンの一つで、特にWebアプリケーション開発で広く使われています。一般的なアーキテクチャの一つです。

MVCは以下の3つのコンポーネントから構成されます：

**・Model（モデル）**
**・View（ビュー）**
**・Controller（コントローラー）**

それぞれが異なる役割を持ち、アプリケーションの機能を分割して扱いやすくしています。
![Controller.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3502812/05562f5f-40d3-bace-a45f-a5f37d0d4dc4.jpeg)
Canvaで簡単に図式化してみました。


## Model（モデル）
・データとビジネスロジックを管理する部分。
・データベースとやり取りし、アプリケーション内でのデータを扱う。
・データのバリデーションを管理する部分。

お気持ちとしては、「**データを正しく管理するお仕事**」
```
class User < ApplicationRecord
  validates :name, presence: true
end
```

## View（ビュー）
・ユーザーに表示する部分（UI部分）。
・HTMLやCSS、JavaScriptなどを使い、データを視覚的に表現する。
・コントローラーから渡されたデータを受け取り、Webページとして表示する。

お気持ちとしては「**どんなデータかは知らないけど、モデルとコントローラーから渡されたデータをユーザーに表示するのがお仕事**」

```
<h1>Welcome, <%= @user.name %>!</h1>
```

## Controller（コントローラー）

ユーザーのリクエストを処理し、適切なモデルやビューを呼び出す。
例えば、URLに対応するアクションを実行し、モデルを利用してデータを取得し、ビューに渡す。

```
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id])
  end
end
```

お気持ちとしては、「ユーザーからリクエストが来たら、最初に対応する場所で、『このデータが欲しい』とか『この情報を送信したい』って頼まれたら、Modelからデータを取ってくるという、モデルとViewの架け橋的存在」




## サービスクラス
サービスクラスの目的とメリット↓

**役割の分離**
コントローラーはリクエストとレスポンスの管理に専念し、サービスクラスにビジネスロジックを委託します。コントローラーの肥大化を避けることに使われます。
モデルはデータベースとのやり取りやバリデーションに集中し、複雑なロジックを避けることができます。

**コードの再利用性**
サービスクラスに切り出すことで、同じロジックを複数のコントローラーやモデルから呼び出せます。


**テストのしやすさ**
ビジネスロジックを独立させることで、サービスクラス単体でテストを行いやすくなります。


これらは、Ruby on Rails のDRY原則にも当てはまりますね。👀

インターン先では、ビジネスロジックはコントローラーには書かず全てサービスクラスに書くように言われましたが、場面によってはアンチパターンになることもあるそうです。


## おわり
この記事がこれからMVCモデルについて学ぶ方の少しでも手助けになればと思います！




## 参考
https://zenn.dev/kibe/articles/2feacfca9c16be

https://qiita.com/os1ma/items/66fb47f229896b32b2e8
リスボンで行われたWebSummit2024へ行ってみた

本記事は[NECソリューションイノベータ Advent Calendar 2024](https://qiita.com/advent-calendar/2024/nes)の12/5の記事です。

ポルトガルのリスボンで行われたWebSummit2024に参加してきたので、簡単なレポートです。

## イベント概要
「Web Summit」は、ポルトガルの首都リスボンに150を超える国々から7万人以上が集結する欧州最大級のテックカンファレンスです。
今年は参加するスタートアップの数は3,000以上、参加する投資家の数は1000を超え、世界でも有数のテックカンファレンスとして認知されています。

## 開催期間
2024/11/11〜14

## 開催場所
ポルトガル・リスボン

## トラック
2024年のトラックは以下15種類。
1. AI Summit
2. Commerce Summit
3. Corporate Innovation Summit
4. Creative Summit
5. Developer Summit
6. Fintech Summit
7. Government Summit
8. Growth Summit
9. Marketing Summit
10. New Energy Summit
11. New Media Summit
12. New Venture Summit
13. People Summit
14. SaaS Summit
15. Startup Summit

## 主要な技術トレンド
カンファレンス全体を通じて、私自身が見られた範囲で以下の技術トレンドが特に注目されていたように感じました。

### AI
- AIの進化とその社会への影響について、EUでの開催の影響もあると思うが、哲学や倫理観や法律などの観点でのディスカッションが目立った
- AIが様々な業態の企業活動にどのように統合されているか（統合されていくか）というセッションが多数あり、特に製造業やサービス業、業務としてはマーケティング領域での応用例が多かった印象
- IT系の企業では、センターを作ってAIノウハウの蓄積をするだけでなく、企業内ガバナンスを働かせる取り組みも見られた
- AI Agentが多く、個人や自社のデータを活用して業務などを支援するAIソリューション（LLM)が多くみられ、特に営業系（Sales＆Marketing）、人事系（採用）、法務などスタッフ系業務のAI Agent化がトレンドにあった

### サステナビリティとグリーンテクノロジー
- 初日の開催イベントでは、CO2からジェット燃料生成する技術など、最新の技術動向が紹介された
- センターステージでのパネルディスカッションにおいて、都市計画におけるサステナビリティの重要性とテクノロジーが果たす役割についてのディスカッションがいくつか行われていた

### フィンテックとデジタル通貨
- 暗号通貨やブロックチェーン技術の進展による金融業界への影響が取り上げられていた
- テクノロジーを活用し銀行がない地域や低銀行化地域（人口減少による銀行が近隣になくなる状態）に対して、金融サービスへのアクセス拡大にディスカッションがあり、銀行が少ない地域課題に対するスタートアップもいくつか展示されていた

### ヘルステックとバイオテクノロジー
- 欧州でもヘルス、ウェルビーイングのトレンドがあり、多くのスタートアップが健康アプリを提供して、エクササイズや教育コンテンツを提供をしている。AI-PoweredやPersonalizedというのもトレンドワードとして多く使われていた
- 健康アプリプロバーダーの差別化要素として、肥満向け、子供向け、女性向けなど特定のターゲットに絞ることが多い
- 多くのヘルスケアスタートアップのビジネスモデルはSaaS型で、B2B（医療機関、企業向け）とB2Cの両方をやっていることろが多かった
- 企業向けの場合は、社員の健康による生産性向上やバーンアウト回避などが購入理由であるとのこと

## スタートアップの動向

### 生成AIの進化と活用

多くのスタートアップが生成AIを利用し、課題解決に役立つプロダクトを開発している印象です。

マーケティングの領域や、パーソナライズされたユーザ体験、教育分野への適用など様々な分野で対応されてきていました。

### 中小企業向けソリューションの増加

生成AIにより、特化した業務であっても割と容易に課題解決が実現できるようになってきたからなのか、製造業などの中小企業のデジタル化になかなか踏み込めなかった課題や、教育事業など今までは高い利益をあげられなかった領域の課題まで解決するソリューションが増加してきてる印象でした。

### ニッチ市場へのアプローチ

船舶用スマートアンカーやスポーツリクルーティングなど、特定のニッチ市場を狙ったソリューションが目立ってました。

## まとめと所感

EUのイベントだけあって、テクノロジーの未来の話だけでなく、倫理観や法律も含めた未来の話を聞くことができ、技術戦略においてはその視点も重要であることを再認識することができました。

その中でもAGI（汎用人工知能）の必要性についてのディスカッションがあり、人間の価値観を逸脱したAGIが発生するリスクがある中で

- 本当にAGIが必要なのか？
- やはり仕事は人間がやるべきでAIはあくまで人間の仕事をサポートをするレベルでいいじゃないか

という提言もあり、テクノロジーは進化をすればいいだけじゃないということに気付かされました。

また、AIと人間の関係性について、とあるスピーカーが「テクノロジーの変化に対応するのも人間がすること」という表現をしていたのが印象に残っています。

実際に現地に行って直接スタートアップの人と会話をしたり、どんなことにみんなが集まって話を聞いているのかを直接見ることで、今の市場がどういう方向に向かっているのか、何にみんなは熱量があるのかを肌で感じることができ、また来年もできたらWebSummitに参加できたらなと強く思いました。


#本記事の内容は個人的な所感や感想であり、組織の公式見解ではありません。
p5jsでスノードームを作る

# はじめに
本稿は [Processing Advent Calendar 2024](https://adventar.org/calendars/9929) への参加記事です。 
最初は技術解説的なことをしようかと思っていたのですが~~時間がなくて~~、作品作りのほうが楽しいかなと思いまして、振ったら雪が舞うスノードームをつくってみました。

# 作ったもの
こちらが作ったものになります。

https://openprocessing.org/sketch/2473345

スマホからアクセスしてデバイスをゆらすと雪が舞います。

![無題の動画-‐-Clipchampで作成.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234113/a461012a-568a-22a5-d67a-4de69188b99a.gif)


パソコンからはクリックで簡易的に雪を舞わすことができます。

![snowdome_pc.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234113/604b5c8a-ffa7-3bd9-9c94-b24be3dd8523.gif)


# ちょっとした解説
### 雪が舞う仕組み

　基本的な仕組みは[matter.js](https://brm.io/matter-js/)を使用し、ドーム内に雪がとどまるようにしています。振って雪を舞わすため、「device motion event」でデバイスの加速度、「device orientation event」でジャイロセンサーの値を取得しています。  
　いろいろ試行錯誤した結果
* ジャイロセンサーの値で画面の傾きを求め重力方向にする
* 加速度を外力として与える  
 
 という形で実装してみました。  
   
### ツリーの種類
　ツリーはランダムで3つ生成するようにしています。レイヤー数や柄が違うのでいろいろ見てみていただけると嬉しいです。

# おわりに
　初のAdvent Calendar参加でした。しっかり文章を書くのが苦手なので、作品メインの参加とさせていただきますした。
 　クリスマスにちなんでいる、自分的にやったことがなかったmatter.jsを使ってみるということができたので個人的には満足です。ただもう少しIMU周りのデータの使い方を追い詰めて本物のスノードームみたいに出来たらよかったなと思います。
　読んでいたみなさま、ありがとうございました！

# 参考
* p5jsとmatter.jsの組み合わせ
 https://github.com/CodingTrain/website-archive
* 加速度の取得
 https://developer.mozilla.org/ja/docs/Web/API/Window/devicemotion_event
* ジャイロセンサーの取得  
https://developer.mozilla.org/ja/docs/Web/API/Device_orientation_events/Detecting_device_orientation
ABC275Dを解いた【メモ化再帰】




筆者はレート800前後の茶～緑コーダ

ABC275のD問題を解いていく

https://atcoder.jp/contests/abc275/tasks/abc275_d



# 実装コード

メモ化再帰というテクニックがあれば一発で解ける問題らしい。

一度計算した値を連想配列に入れればいいということで個人的に頼れる味方であるdefaultdict君に頑張っていただこう。[^dict]

初期値が入っていれば計算、それ以外だったら計算済なのでその値を返すようにする。

[^dict]: 普通のdictでも`not in`で判定すればできるようだが、初期値が入っていれば計算のほうが個人的にわかりやすいのでこちらを使うことにした。

```python:main.py
from collections import defaultdict
df=defaultdict(lambda:0)
df[0]=1
def f(x):
    if df[x]==0:df[x]=f(x//2)+f(x//3)
    return df[x]
print(f(int(input())))
```

メモ化再帰について調べてみたが、それ専用(?)のデコレーターとして`functools.lru_cache`があるようだ。

```python:main.py
from functools import lru_cache
@lru_cache
def f(x):
    if x==0:return 1
    else: return f(x//2)+f(x//3)
print(f(int(input())))
```


# まとめ

ABC275のD問題を解いた。

メモ化再帰を`defaultdict`で実装して解いたが、メモ化再帰用のデコレーターとして`functools.lru_cache`が存在していることも知った。

再帰関数を使った実装はまだまだ慣れていないところがあり、勉強になった。
ソフトウェアのインストールとアンインストール（連載第20回/25回）

# はじめに
Linuxシステムでは、ソフトウェアのインストールとアンインストールはよく行われる作業です。ここでは、主要なパッケージマネージャー（`apt`、`yum`、`dnf`）と、ソースからのインストール方法（`make`、`install`、`uninstall`）について説明します。

# コマンド説明
#### `apt` - Debian系ディストリビューション用パッケージマネージャー

`apt` は、DebianおよびUbuntuを含むDebian系ディストリビューションで使用されるパッケージマネージャーです。

```powershell
# ソフトウェアのインストール例
sudo apt update
sudo apt install パッケージ名
# ソフトウェアのインストール
sudo apt update
sudo apt install vim
# ソフトウェアのアンインストール例
sudo apt remove パッケージ名
sudo apt remove vim
```

#### `yum` - Red Hat系ディストリビューション用パッケージマネージャー
`yum` は、CentOSおよびRHELを含むRed Hat系ディストリビューションで使用されるパッケージマネージャーです。

```powershell
# ソフトウェアのインストール：
sudo yum install パッケージ名
sudo yum install vim
# ソフトウェアのアンインストール：
sudo yum remove パッケージ名
sudo yum remove vim
```

#### `dnf` - Fedora用パッケージマネージャー
`dnf` は、Fedoraおよび最新のRed Hat系ディストリビューションで使用されるパッケージマネージャーです。

```powershell
# ソフトウェアのインストール：
sudo dnf install パッケージ名
sudo dnf install vim
# ソフトウェアのアンインストール：
sudo dnf remove パッケージ名
sudo dnf remove vim
```

#### `make`、`install`、`uninstall` - ソースからのインストール
ソースコードからソフトウェアをインストールするには、一般的に以下の手順に従います。

```powershell
ソースコードのダウンロード：
wget http://example.com/software.tar.gz
tar -xzf software.tar.gz
cd software
# コンパイルとインストール：
bash
./configure
make
sudo make install
# アンインストール：
sudo make uninstall
# 特定のバージョンのパッケージをインストール
sudo apt install パッケージ名=バージョン番号
# パッケージとその依存関係を一緒に削除
sudo apt autoremove パッケージ名
# リポジトリを追加して新しいソフトウェアをインストール
sudo add-apt-repository ppa:example/ppa
sudo apt update
sudo apt install 新パッケージ名
```

# おわりに
ソフトウェアのインストールとアンインストールの基本的なコマンドを理解し、適切に使用することで、システムの管理が効率的に行えます。

次からの記事では、ユーザーとグループの管理について解説します。

https://qiita.com/yu1016/items/c5b8673b3a6672fc3ca1

一覧

https://qiita.com/advent-calendar/2024/pig
【TIPS】マップリストからキーで値を抜き出す

この記事は、[Elixir Advent Calendar 2024 シリーズ7](https://qiita.com/advent-calendar/2024/elixir) の5日目です

---

【本コラムは、4分で読め、4分で試せます】

[piacere](https://twitter.com/piacere_ex) です、ご覧いただいてありがとございます :bow:

マップリストからキーで値を抜き出すには、こんな感じです（Map.valuesのマップリスト版みたいなものです）

```diff_elixir
key = "name"
[%{"name" => "c2", "age" => 21}, %{"name" => "c4", "age" => 42}] 
|> Enum.map(& &1[key])

結果：["c2", "c4"]
```

ただし、キーが欠けている場合は、nilが返ってしまいます（その仕様でOKというケースもありますが）

```diff_elixir
key = "name"
[%{"age" => 21}, %{"name" => "c4", "age" => 42}] 
|> Enum.map(& &1[key])

結果：[nil, "c4"]
```

なので、キー欠け対策をしたいなら、少し工夫が必要です

```diff_elixir
key = "name"
[%{"age" => 21}, %{"name" => "c4", "age" => 42}] 
|> Enum.map(& &1[key])
|> Enum.reject(& &1 == nil)

結果：["c4"]
```

なお、上の方法だと、キー欠けか、値がnilかを厳密には区別できないため、別の工夫が必要です

```diff_elixir
key = "name"
[%{"age" => 21}, %{"name" => "c4", "age" => 42}] 
|> Enum.map(& Map.take(&1, [key]))
|> Enum.reject(& &1 == %{})
|> Enum.map(& &1[key])

結果：["c4"]

key = "name"
[%{"name" => nil, "age" => 21}, %{"name" => "c4", "age" => 42}] 
|> Enum.map(& Map.take(&1, [key]))
|> Enum.reject(& &1 == %{})
|> Enum.map(& &1[key])

結果：[nil, "c4"]
```

# p.s.このコラムが、面白かったり、役に立ったら…

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155423/907a8695-4d83-1b5c-8052-d0ce52de5f66.png) にて、どうぞ応援よろしくお願いします :bow:
レガシーシステムの解決法について

# はじめに

各組織がレガシーシステムを抱えて困っていることは多いのではないでしょうか?
ただ、困っている事情はそれぞれ異なると思います。
そこで、いくつかの共通点を挙げつつ、どう対処していけば よいかを考えてみました。

# わかる人がいなくなった

これが一番多い問題でしょう。
まず、「人が足りなくてアサインできない」というのは別問題としておきます。 
ここで重要なのは、「技術スタックを持っている人がいない」もしくは「アサインできる状況にない」ということです。
これは組織として解決すべき課題です。
組織の規模や状況に応じて取りうる手段は以下の通りです。

1.研修を通じて必要な知識を学び、分析を行った上で担当として経験を積む
- コストは比較的安い。
- 本人の意欲低下を防ぐ配慮が必要。

2.関連技術の経験を持つ技術スタッフを雇う
- 雇用形態によってランニングコストが高くなる。

3.外部業者と保守契約を結ぶ
- ランニングコストが高い。

4.現在の人員で賄える技術でリプレイスする
- 初期コストが高い。

# OSやOfficeのバージョンへの追従が大変である。

技術者や保守作業者の立場からすると、最新バージョンへの追従は重要です。
しかし、それが実際にコスト削減や収益増加に繋がるかを考える必要があります。

具体的には、次のような点を検討します:
- OSやOfficeバージョンへの追従コスト
- 追従しないことで発生することが見込まれるコスト(インシデントを含む)

これらの要素を明確にすることで、対策に対する納得感を得られやすくなります。

# ライセンス費用が高い

サーバーやDBMSのOSS化はライセンス費用の削減に有効です。以下の点を考慮します:
- アプリケーションレベルでの書き換えは、DBアクセス層の差し替えで多くの場合対応可能。
- 初期コストは比較的低いが、機器調達には費用がかかる。
- OSS化には管理者の高度な知識が必要で、学習コストも発生する。

ただし、AccessなどのOfficeライセンス削減という趣旨の場合は、導入規模によっては大きな効果が期待できない場合があります。

# 終わりに

レガシーシステムが作られた経緯はさまざまで、特定の人が作った便利ツールが広まったり、 古いプロジェクトが今も使われていたりします。
やめたい、どこかに投げたいという気持ちが先行するのはわかりますが、「わからないからやらない」ではなく、「学習してわかるようになる」という方向もあるのではないかと思います。
ファイルの比較と差分の確認（連載第19回/25回）

# はじめに
ファイルの内容を比較し、差分を確認することは、ソースコードの変更や設定ファイルの更新など、多くのシナリオで重要です。ここでは、`diff` と `cmp` の基本的な使い方を紹介します。

# コマンド説明
#### `diff` - ファイルの差分を表示

`diff` コマンドは、2つのファイルの違いを行単位で比較し、差分を表示します。一般的に、ソースコードのバージョン管理やテキストファイルの変更点の確認に使用されます。

***主なオプション***
-u : ユニファイド形式で表示
-c : コンテキスト形式で表示
-i : 大文字と小文字を無視して比較
-r : ディレクトリを再帰的に比較


```powershell
diff [オプション] ファイル1 ファイル2
# 2つのファイルをユニファイド形式で比較：
diff -u file1.txt file2.txt
# 2つのディレクトリを再帰的に比較：
diff -r dir1/ dir2/
# テキストファイルの変更点を確認
# このコマンドは、2つのテキストファイルの差分をユニファイド形式で表示します。
diff -u old_version.txt new_version.txt
# ディレクトリ全体の差分を比較
# このコマンドは、2つのディレクトリの差分を再帰的に比較します。
diff -r project_old/ project_new/
```

#### `cmp` - バイナリファイルの比較
`cmp` コマンドは、2つのファイルをバイト単位で比較し、最初に異なるバイトを表示します。バイナリファイルやテキストファイルの比較に使用されます。

***主なオプション***
-l : 異なるバイトの場所と値を表示
-s : 異なるバイトが見つかった場合、メッセージを表示せずに終了ステータスを返す

```powershell
cmp [オプション] ファイル1 ファイル2
# 2つのファイルをバイト単位で比較：
cmp file1.bin file2.bin
# 異なるバイトの場所と値を表示：
cmp -l file1.bin file2.bin
# バイナリファイルの違いを確認
# このコマンドは、2つのバイナリファイルの最初の違いを表示します。
cmp file1.bin file2.bin
# 異なるバイトの詳細情報を表示
# このコマンドは、異なるバイトの場所と値を表示します。
cmp -l file1.bin file2.bin
```

# おわりに
ファイルの比較と差分の確認の基本的なコマンドを使用することで、ファイルの変更点を効率的に特定し、必要な対応を迅速に行うことができます。

次からの記事では、ソフトウェアのインストールとアンインストールについて解説します。

https://qiita.com/yu1016/items/012688567f02d266b901

一覧

https://qiita.com/advent-calendar/2024/pig
Android Studioのアップデートで起こるエラー(emulator)

## Android Studioとは
Android Studio は Google が開発し配布する、Android アプリ開発用の公式の統合開発環境（IDE）です。
Androidのモバイルアプリ開発言語には【kotlin】と【Java】があります。

## Android Studioのアップデート
定期的にAndroid Studioにはアップデートが入ります。
そのたびにAndroid Studioとemulatorのバージョンが変わります。
最新版になるからいいじゃん！とも思いますがこれがのちに私の時間を2日奪うことになりました。

## どこが問題だった？
## 1.プロジェクト作成時のバージョンがプロジェクトに書き込まれる
私がプロジェクトを作成した際に、【build.gradle.kts】にemulatorの対応したバージョンが書き込まれます。まず【compileSdk】、次に【minSdk】、そして【targetSdk】です。【minSDK】に関しては古いバージョンをどこまで使えるようにするかなのでそこまで関係ないとのことでした。![スクリーンショット (38).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881358/a32d3674-c601-c9eb-0a49-2b805779c8c0.png)

## 2.アップデートが来た際に書き換えなければいけない
私はアップデートが来たことを知らずに、久々にAndroid Studioを触りました。
軽くコードをいじりビルドしてみるとあら不思議。一切ビルドされず5分待たされエラー。どうしたんだいマイハニー。自分自身ほとんど知識がなくとりあえずGPTにぶん投げるととりあえず【build.gradle.kts】を書き換えればいいらしい。

## 3.ファイルの場所がわからない
GPTに教えてもらったはいいものの、【build.gradle.kts】のファイルがどこにあるのか全く分からない。どこにあるのかGPTにまた投げても今度は見当違いな回答ばかりでした。ここで一日目終了。2日目、2時間ほどGPTとAndroid Studioを行き来しやっとのこと【build.gradle.kts】を見つけることができました。

## 4.書き換えても治らない
ファイルを見つけることができいざ古いバージョンを現行バージョンに書き換え、わくわくウキウキビルディングターイム。これがつかねぇんだよなぁ。なんでや。バージョン変えたやん。俺の時間を何だと思っとるん？とパソコンに切れながらまたGPTと会話をしているとどうやらemulatorのバージョンと使っているemulatorが違うらしい。。。![スクリーンショット (39).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3881358/c2e9fffe-f210-e91d-79c1-56a9a139fad9.png)
写真の通り【build.gradle.kts】のバージョンは最新(35)だが使っているemulatorが一世代前(34)のものでした。やっとこさ見つけ、最新のemulatorをダウンロードし両方のバージョンをそろえることができました。

## 5.それでもカブは抜けません
全然動かん。もういいかな。Android mobile engineer向いてないや。しらん。そうしょぼくれていると、先輩にemulator入れ直してみたら？とアドバイスをいただきました。ここまで来たらなんでもやる思いで即入れ直しました。さぁどうだ？

## 6.二度あることは三度ある
まぁそうだよなと。ここまで動かなかったら、もう無理よな。うんうん。俺頑張った。と自分を励ましながら、GPTと会話を続けること1時間。ついに諦めました。もう俺のAndroid studioは動かないんだ。と萎えながらPCを落とし帰宅。あの日の絶望感はすごかった気がします。自分の出来の悪さに嫌気がさしエンジニアすら向いてないんじゃと思いながら寝ました。次の日。emulator「Install successfully finished in 7 s 539 ms.」ニコニコで起動してくれました。結局は再起動すれば全部何とかなるんですねこれが。

## 結論
やっぱ諦めずに試し続けるの大事です。
あと再起動はしましょう。新しいソフトウェアを入れたとき、アップデートしたときとりあえず再起動しましょう。マジで変なバグ減る！
Android Studioでは定期的にアプデ来るんで確認したほうがいいです。
今はテントウムシ君が最新だよぉー！
[JavaScript]コーディングパターンについて

### ※この記事を書いてる人はほぼ未経験の初心者です。
私は現職の会社で社内SE...みたいなことをさせていただいています。
なのでほぼ初心者みたいなものであるという前提でこの記事を読んでいただけると幸いです。
## 皆さんはどのように関数を定義していますか？
以下の2種類が主に使用されていると思います。
```javascript
// functionキーワード
function multiplyNibai(num){
    return num * 2
}

// アロー関数
const multiplyNibai = num => num * 2;
```

### コーディングパターン

```javascript:パターン1 - functionキーワード
// グローバル変数はなるべく定義せず、名前空間汚染を防ぐためにオブジェクトとして定義します。
// ここにはオプションとなる定数などを定義します。
const App = {
    API_URL: "www.dokokano.api.com",
    LOADED: null
}

// メイン関数
async function main() {
    setupListeners()
    App.LOADED = await loadSomeNanika();
}
main();

// メイン関数の下に主要な関数を定義
function setupListeners() {
    // コールバック関数にはアロー関数で書くとスッキリ書けて良い
    document.querySelector(".someInput").addEventListener("change", e => {
        consoleLoger(e.target.value);
    })

    // 主要関数の一番下にサブ関数を定義
    function consoleLoger(message) {
        console.log(message);
    }
}

// 主要な関数
async function loadSomeNanika() {
    const response = await fetch(App.API_URL);
    const res = await response.json();
    const result = toUnti(res);
    return res;

    // 主要関数の一番下にサブ関数を定義
    function toUnti(data) {
        return data + "unti"
    }
}
```

```javascript:パターン２ - アロー関数
const App = {
    API_URL: "www.dokokano.api.com",
    LOADED: null
}

// メイン関数の下に主要な関数を定義
const setupListeners = ()=>{
    // constなので上に書くしかないサブ関数
    const consoleLoger = (message) {
        console.log(message);
    }
    
    // コールバック関数にはアロー関数で書くとスッキリ書けて良い
    document.querySelector(".someInput").addEventListener("change", e => {
        consoleLoger(e.target.value);
    })
}

// 主要な関数
const loadSomeNanika = async()=>{
    // constなので上に書くしかないサブ関数
    const toUnti = ()=>{
        return data + "unti"
    }
    
    const response = await fetch(App.API_URL);
    const res = await response.json();
    const result = toUnti(res);
    return res;
}


// メイン関数
const main = async ()=>{
    setupListeners();
    App.LOADED = await loadSomeNanika();
}
main();
```
私は普段パターン1で書いていて、メイン関数を一番上に、主要な関数などを下に書くことでメイン関数の見通しがよくなると思っています。
この記事を読んでいただいた方はこのほうがよくね？俺はこう書いてる！とかあればぜひ気軽にコメントに書いてもらえると嬉しいです(';')！

### function関数とアロー関数の主な違い
**function関数**
・巻き上げ(ホイスティング)が起こるのでスコープ内ならどこに書いてもよい

**アロー関数**
・超スッキリ書ける

たくさん違いがあるので詳しくは以下を読んでみてください。
https://typescriptbook.jp/reference/functions/function-expression-vs-arrow-functions
東京都オープンデータハッカソンに初参加した話

東京都オープンデータハッカソンに初出場してきました！感想や学びをぽろぽろ書きます
ちなみにハッカソンは大学生1年生の時に1回だけ出場経験あり（その時は何もできず苦い思い出だ)
![IMG_5728.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397581/294f3af3-5f91-7cf9-d677-da7e3730c640.jpeg)


## そもそもハッカソンとは？
「エンジニアやデザイナーがそれぞれの技術やアイデアを持ち寄り、短期間に集中してアプリケーションなどを開発し、成果を競う開発イベント」
個人的な見解だが、最近は非エンジニア参加型のハッカソンが増えているイメージ。

## ほんなら東京都オープンデータハッカソンの意義は？
"東京都は、社会課題を解決する手段として、オープンデータとテクノロジーを活用した「[都知事杯オープンデータ・ハッカソン](https://odhackathon.metro.tokyo.lg.jp)」を今年度も開催します。"
と公式サイトに記載があるとおり、東京都が抱えている社会課題に対して何か解決/改善するアイディアを出し合おうと言った企画だ。
どうやら今年(2024年)は4度目らしく、さらに年々規模は拡大しているとのこと。

このイベントのキーワードは「**オープンデータ**」
東京都が整備しているオープンデータを使うというのがこのハッカソンの制約かつ魅力だ。

## では東京都が整備したオープンデータとはどんなものか？
[東京都オープンデータカタログサイト](https://portal.data.metro.tokyo.lg.jp)と言うものがあるらしいので早速見てみよう。
・土地利用現況調査GISデータ
・浸水予想区域図
・東京消防庁 消火栓及び防火水槽等
・東京都防災マップ避難所・避難場所一覧データ
（アクセスランキングから抜粋）

さらにカテゴリー別にデータが整理されており、「まちづくり」「観光」「医療」と言った具合に興味のあるテーマからも探せそうだ。

実際にデータの中身を見てみよう。試しに都内の公衆トイレのデータを集めてみた。
そこで気づいた。

「**あれ、市区町村でデータセットが分かれてる**」

ちょっとしたサプライズ。
そうか、データは市区町村単位で集められてるケースも多いんだな。

そもそも東京都オープンデータカタログと言ってるくらいなので、全国ではなく**東京都**のデータしかないのか。

普段は民間企業や国際機関、気象庁などのデータを扱うことが多い私にとっては、行政のデータの特徴を知るきっかけとなった。

## 地域の課題解決に大切な視点
私は学生の頃、「国際協力には**グローバルな視点**と**ローカルな視点**、どちらも欠かせない重要な視点だ」と何度も聞かされた。

今回のハッカソンでは東京都の課題について考えるのだが、私はどうしても**外の視点**と**中の視点**、両方から東京の課題を考えてみたかった。

今年のハッカソンでは、初めて都の職員の方が課題を提示している。
今まではハッカソン参加者が独自に課題を設定するパターンのみだったようだ。

とは言え、私は疑問に思った。

**職員の人は本当に東京の課題を認識しているだろうか？**
**実際に都民にヒアリングしたのだろうか？**

職員の方を疑いたいわけではない。
しかし個人的には、課題の設定は何よりも*面白い作業*だと思うので、自分たちで決めたかった。
そして私は都民ではない。だからこそ、東京の課題を的確に当てられる自信がないと思った。

私達のチームは課題の抽出にも*データ*を使った。

データには質的/量的データと大きく2種類に分けられる。
人間が抱える要望や課題の抽出には、この質的データであるアンケートやインタビューといった情報が役に立つ。
都民が回答している場合は**内の視点**。
観光客、もっと言えば海外からの観光客が回答している場合は**外の視点**になる。

他のチームでは、チームメンバーが抱えている身近な課題や、データを扱う人だからこそ気がつく課題などあらゆる方法で考えられており興味深かった。

## 最後に感想
総じて、楽しかった。
チームの仲間とたくさん考えて、何か一つのアイディアを形にする。その営みが楽しかった。
そしてこのような機会を用意してくれた運営スタッフには感謝です。

私達は職場の仲間で出場した。それゆえに新しい出会いは特になかったが、言いたいことを遠慮せずに言える。
そんな環境と仲間に恵まれ、約9年ぶりのハッカソンは良き思い出となりました。

もし、ハッカソンに参加するか悩んでいる方がいたら「とりあえず参加してみたら?」とは言えないが、**周りに恵まれたら楽しいものになるかもしれない。**
そんな期待を胸に参加してみても良いかも。

-------
読了ありがとうございました。
【備忘録】.gitignoreに追記した後にGitの管理下に入ってしまう場合

.gitignoreに自分用のメモを記入していた「memo.txt」というファイルを追記したのですが、gitの管理下に入ってしまうという問題に直面しました。
以下の方法でgit管理下から除外できました。

まず以下のコマンドを試す。
```
git rm --cached memo.txt
```

それでも解決しない場合は次を試す。
```
git rm -r --cached .
git add .
```
以上の方法で.gitignoreへの追記が反映できました。
セキュリティ対策（連載第18回/25回）

# はじめに
システムのセキュリティ対策は、ネットワークやデータの保護において非常に重要です。ここでは、`iptables` と `fail2ban` の基本的な使い方を紹介します。

# コマンド説明
#### `iptables` - パケットフィルタリングとファイアウォール

`iptables` コマンドは、Linuxカーネルのネットフィルタモジュールを制御して、パケットフィルタリングやネットワークアドレス変換（NAT）を行うツールです。

***主なオプション***
-A : ルールをチェーンの末尾に追加
-D : ルールを削除
-I : ルールをチェーンの先頭に挿入
-L : ルールの一覧表示
-F : ルールを全て削除

```powershell
iptables [オプション]
# SSHポート（22番）への接続を許可：
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
# 特定のIPアドレスからの接続を拒否：
sudo iptables -A INPUT -s 192.168.1.100 -j DROP
# 現在のルールを表示：
sudo iptables -L
# ファイルの転送中にFTPポートを許可
sudo iptables -A INPUT -p tcp --dport 21 -j ACCEPT

```
#### `fail2ban` - 不正アクセスの防止
`fail2ban` は、ログファイルを監視し、不正アクセスの試行を検出してIPアドレスを一時的にブロックするツールです。主にSSH攻撃やBrute Force攻撃からの保護に使用されます。

```powershell
# インストール：
sudo apt-get install fail2ban    # Ubuntu/Debian
sudo yum install fail2ban        # CentOS/Fedora
```

```powershell
# 設定ファイル（ini）の編集： 
# 設定ファイルは /etc/fail2ban/jail.local にあります。
# このファイルで、監視するサービスやブロックするポリシーを設定します。

# SSHの設定
[sshd]
enabled = true
port = ssh
logpath = /var/log/auth.log
maxretry = 5
```

```powershell
# サービスの起動と有効化
sudo systemctl start fail2ban
sudo systemctl enable fail2ban
```

```powershell
# ステータスの確認：
sudo fail2ban-client status
# 特定のサービスのfail2banステータスを確認
sudo fail2ban-client status sshd
# ブロックされたIPアドレスをアンバン
sudo fail2ban-client set sshd unbanip 192.168.1.100
```

# おわりに
セキュリティ対策の基本的なコマンドを使用することで、システムの安全性を向上させ、不正アクセスから保護することができます。

次からの記事では、ファイルの比較と差分の確認について解説します。

https://qiita.com/yu1016/items/17bfd975b48370277ffb

一覧

https://qiita.com/advent-calendar/2024/pig
MudBlazor のグリッドシステムで画面をレスポンシブに

# MudBlazor を使っています

[マークシートシステム Mark2](https://omr.mark2.org/) では UI コンポーネントに MudBlazor を利用しています。2024年12月時点では以下のような画面になっています。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238166/5e35293a-3477-7c97-e6b6-c10aa46c5e39.png)

ブラウザのサイズを変更してみるとボタンが縦長になってしまいました。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238166/8f3e99fe-e15b-63eb-ffa7-036bfbd1d0af.png)

Mark2 は PC から利用する前提なので、このような表示を目にする人は少ないと思うのですが、レスポンシブデザインを意識していきたいと思いました。

MudBlazor も Bootstrap と同様にグリッドレイアウトができるようです。

https://mudblazor.com/components/grid

# 画面サイズに応じた設定を追加

Mark2 の画面をレスポンシブにする設定は悩ましい部分もあるのですが、ひとまず `xs` と `md` の場合を設定しました。

```diff_html
- <MudItem xs="4">
+ <MudItem xs="6" md="4">
    ....
</MudItem>
- <MudItem xs="8">
+ <MudItem xs="6" md="8">
    ....
</MudItem>
```

さきほどよりはボタンの文字が読みやすくなったかと思います。

![スクリーンショット](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2238166/be351754-3d95-268e-87b2-a0c4ec4b8412.png)

# MudBlazor 8 is coming soon

MudBlazor はプレリリースとして v8.0.0-preview.5 が公開されています。

https://github.com/MudBlazor/MudBlazor/releases

Mark2 の画面は2020年に最初のリリースをしたときからほとんど変わっていなくて、最近の MudBlazor の進歩が取り込まれていない状況です。 Mark2 は学校や自治体のユーザーが多いので、自分としても画面の変更には消極的でした。しかし、そろそろアップデートを考えてもよい時期だと考えていて、 MudBlazor 8 がリリースされたら Mark2 の画面もゼロから再構成する予定です。
DB設計について②

## 論理設計と物理設計
### DBをマスターしたい
前回に引き続き、DBの基本知識を学習している
今回は論理設計と内部設計のポイントについてまとめる

#### 参考文献
[達人に学ぶDB設計徹底指南書](https://www.amazon.co.jp/%E9%81%94%E4%BA%BA%E3%81%AB%E5%AD%A6%E3%81%B6DB%E8%A8%AD%E8%A8%88-%E5%BE%B9%E5%BA%95%E6%8C%87%E5%8D%97%E6%9B%B8-%E5%88%9D%E7%B4%9A%E8%80%85%E3%81%A7%E7%B5%82%E3%82%8F%E3%82%8A%E3%81%9F%E3%81%8F%E3%81%AA%E3%81%84%E3%81%82%E3%81%AA%E3%81%9F%E3%81%B8-%E3%83%9F%E3%83%83%E3%82%AF/dp/4798124702)

---
### 目次
1. 概念スキーマと論理設計
1. 内部スキーマと物理設計
1. ストレージの冗長構成
1. バックアップ設計
---

### 1.概念スキーマと論理設計
#### システム設計の手順
論理設計→物理設計の順に設計する
論理設計「物理層の制約にとらわれない」ため論理設計が先立つ

#### 論理設計のステップ
1. エンティティの抽出
エンティティは日本語訳で「実体」
データベースだと、実体ではなく概念でもデータになるものであればエンティティ
どのようなエンティティが必要になるのか抽出するのが第１ステップ<br><br>
1. エンティティの定義
各エンティティがどのようなデータ（「属性」）を保持するかを決める
リレーショナルデータベースだと、どのような「属性」＝「列」をもつか定義する
特に重要なのは「キー(key)」と言う列を定義すること<br><br>
1. 正規化
システムでの利用がスムーズに行えるよう整理する作業
更新が整合的に行えることが重要な目的<br><br>
1. EーR図の作成
大量のエンティティ同士の関係を把握するため

### 2.内部スキーマと物理設計
#### 物理設計のステップ
1. テーブル定義
概念スキーマをもとに「テーブル」の単位に変換していく作業<br><br>
1. インデックス定義
インデックスは本の索引のイメージに近い
必要なデータをコンピュータが探すときに、効率が良くなる
＝パフォーマンスに影響する<br><br>
1. ハードウェアのサイジング
システム開発でいう「サイジング」は2種類の意味
1つ目は「サイズ」の見積もり
　必要なデータサイズを見積り十分なストレージを選定する
2つ目は、パフォーマンス関わるもの
　十分なスペックを発揮できるような CPUやメモリを持ったサーバーの選定
　ストレージのI/Oネックが起きないようにする

### 3.ストレージの冗長構成
#### 冗長構成
データベースに保管されるデータは業務の期間データなので失うことは許されない
可能な限り高い耐障害性を持つようにシステムを構築する必要がある
ここで登場する技術がRAID(Redundant Array of Independent Disks)である
#### RAID
* RAIDとは
複数のディスクを束ねて仮想的に1つのストレージとする技術<br><br>
* メリット
冗長化→複数のディスクに同じデータを書き込むことで一本が壊れても保全できる
性能向上→データを分散して保持するのディスクI/Oが分散される<br><br>
* RAIDの種類
RAID0：複数のディスクにデータを分散。しかし、1つ壊れたら復元は不可
RAID1：2本のディスクに全く同じデータを保持、信頼性UPだが性能は変化なし
RAID5：最低3本で構成し、データとともに「パリティ」を格納
RAID10：RAID1とRAID0の組み合わせ、信頼性/性能UPだがコストも高い

#### ファイルの物理配置
RAIDグループを適用して、どのディスクに配置するかを考える
1. データファイル
データベースに格納するデータを保持するためのファイル
業務アプリがSQLを通じて参照および更新を行う<br><br>
1. インデックスファイル
テーブルに作成されたインデックスが格納されるファイル
DBMSではテーブルととインデックスは普通異なるファイルとして管理される<br><br>
1. システムファイル
DBMSの内部管理用に使われるデータを格納する
基本的に業務アプリケーションやユーザーがアクセスすることはない<br><br>
1. 一時ファイル
DBMS内部での一時的なデータを格納するために使う
例えば、サブクエリを展開したデータやGROUP BYやDISTINCTを利用したソートデータ
処理が終了すれば削除されてなくなるので継続的にサイズ増加はしない<br><br>
1. ログファイル
別名はトランザクションファイルと呼ぶ
データファイルに反映が終われば不要になる

|  | 用途 | ユーザーからのアクセス | データ量の継続的増加 | 性能の考慮レベル |
|:-:|:-:|:-:|:-:|:-:|
| データファイル　   | テーブルデータの格納  |有(テーブル経由) |有|高|
|インデックスファイル|インデックスの格納    |有（インデックス経由）|有|高|
|システムファイル   |管理用データの格納|原則無し（DBAのみ有）  |有|低|
|一時ファイル  |一時データの格納   | 無  |無|高|
|ログファイル   | 更新ログの格納  | 無 |無|中|

### 4.バックアップ設計
#### バックアップの基本分類
1. フルバックアップ
・ある時点での全てのデータをバックアップする方式
・バックアップの時間が長い
・ハードウェアリソースへの負荷が高い
・サービス停止が必要
1. 差分バックアップ
・フルバックアップからの差を保管する方式
・ログファイルからバックアップする
・フルバックアップと最新の差分ファイルが必要
1. 増分バックアップ
・フルバックアップから更新毎のファイルが必要
・ログファイルからバックアップする
・フルバックアップと都度都度の差分ファイルが必要
AWS SAMでAPIKeyを発行するときに気を付けること

# 概要
SAM形式でAPIKeyを発行しようとした時にハマったので、備忘録として残します
# 結論
DependOnで以下の設定が必要
    
    <APIの論理ID>Stage

# 対象者
- CloudFormationでテンプレートがかける
- SAM形式で書いてみたい
- APIKeyを発行したい

# 失敗するテンプレート
デプロイに失敗するAPIKeyのテンプレートを載せます
※他に色々と定義が必要なリソースはありますが、割愛
```
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn:
      - ApiGateway
    Properties: 
      Enabled: true
      Name: !Sub ${ApplicationName}-API-Key-${EnvNameLower}
      StageKeys:
        - RestApiId: !Ref ApiGateway
          StageName: !Ref EnvNameLower

  ApiUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn:
      - ApiKey
    Properties:
      UsagePlanName: !Sub ${ApplicationName}-API-Usage-Plan-${EnvNameLower}
      ApiStages:
          - ApiId: !Ref ApiGateway
            Stage: !Ref EnvNameLower
      Throttle:
        BurstLimit: 100 #TODO: 正式に決定する必要あり
        RateLimit: 50 #TODO: 正式に決定する必要あり
```
上記のテンプレートを実行すると以下のようなエラーがでます
```
Resource handler returned message: "Invalid stage identifier specified (Service: ApiGateway, Status Code: 404, Request ID....
```
stageが定義されてないよ！　的な内容で怒られます
## そもそもstageなんて定義していないよ
自分の書いたテンプレートを見てもstageなんてリソースは書いていません。
では、なぜ発生するのか？
きちんと解析はできていませんが、SAMでは定義していなくもStageリソースが作られているような感じです
### 時系列にまとめると
1. APIGatewayのリソース作成が始まる
1. Stageリソースが背後で始まる
1. APIKeyリソースの作成が始まる
1. Stageリソースが完成していないので、APIKeyのリソース作成で失敗する

# 問題を解決するテンプレート
割愛した部分も含めて今回の問題を解決するテンプレートです
```
  ApiGateway:
    Type: AWS::Serverless::Api
    Properties:
      Name: !Sub ${ApplicationName}-${EnvNameLower}
      Description: API
      StageName: !Ref EnvNameLower
      ApiKeySourceType: HEADER
      Auth:
        ApiKeyRequired: true
        
  ApiKey:
    Type: AWS::ApiGateway::ApiKey
    DependsOn:
      - ApiGateway
      - ApiGatewayStage # これを追加
    Properties: 
      Enabled: true
      Name: !Sub ${ApplicationName}-API-Key-${EnvNameLower}
      StageKeys:
        - RestApiId: !Ref ApiGateway
          StageName: !Ref EnvNameLower

  ApiUsagePlan:
    Type: AWS::ApiGateway::UsagePlan
    DependsOn:
      - ApiKey
      - ApiGatewayStage　# これを追加
    Properties:
      UsagePlanName: !Sub ${ApplicationName}-API-Usage-Plan-${EnvNameLower}
      ApiStages:
          - ApiId: !Ref ApiGateway
            Stage: !Ref EnvNameLower
      Throttle:
        BurstLimit: 100
        RateLimit: 50

  ApiUsagePlanKey:
    Type: AWS::ApiGateway::UsagePlanKey
    DependsOn:
      - ApiUsagePlan
    Properties: 
      KeyId: !Ref ApiKey
      KeyType: API_KEY
      UsagePlanId: !Ref ApiUsagePlan
        
```

# まとめ
SAMを使うと記載量が減るなどのメリットはありますが、その分リソース全体の繋がりが見えづらくなるなどの功罪もありますね
【Chrome拡張機能】荒らしコメントを非表示にする拡張機能を作った

# はじめに
インターネットが普及し、だれでも簡単にコメントを投稿できるようになった今、荒らしコメントで頭を抱える人がたくさんいます。


![実際のコメント](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930283/b5d0e4df-412d-2bcc-2dfb-5de681b4307c.jpeg)


これが今のYoutubeのコメント欄です。こんなことになっていたらコメントする気もなくなってしまいます。この状況を少しでも解決できるように、僕はChrome拡張機能で平和なコメント欄を取り戻そう!と思い制作に取り掛かりました。

# ダウンロード
[Comment Blocker - Github](https://github.com/Cheesecake2960/Comment-Blocker)
(Chromeウェブストアは公開がめんどくさいので出来ませんでした)

# おわりに
この拡張機能がちょっとでも役に立って欲しいと思います。
読んでいただきありがとうございます。