OmniAICreator/Qiita-1.07M huggingface dataset:
記事等の TOC 生成ブックマークレット

記事やチュートリアルを読み進めるにあたりコンテンツの全体を把握したいと思い、ブックマークレットを作成しました。
実行後、エディター等に貼り付けるとマークダウン形式で見出しの一覧がコピーされます。

```js
javascript:{let h=document.querySelectorAll("h2,h3,h4,h5,h6"),r="";for(let{localName:l,textContent:t}of h)if(t=t.trim())r+="  ".repeat(l.slice(1)-2)+t.replace(/^(?!\d+\.\s)/,"- ")+"\n";navigator.clipboard.writeText(r.trim()).then(()=>alert("目次をコピーしました"))}
```

(記事ページなどでブックマークレット実行後) ペーストすると以下のような感じになります。
(**[追記]** h1 はページに１つでタイトルと同じなケースが多そうだったので弾きました。)

```markdown
- h2 のテキスト
  - h3 のテキスト
    - h4 のテキスト
  - h3 のテキスト
    1. 番号付き見出しのテキスト
    2. 番号付き見出しのテキスト
```

簡素化のため、番号付き見出しは箇条書きなしに、また、テキストが無い物は弾いてます。

上記のコードは手動で minify 済みですが、元の JS Code は以下になります。  
使えそうだったら必要に応じて調整ください。

```js
const headings = document.querySelectorAll("h2, h3, h4, h5, h6");
let result = "";

for (let { localName, textContent } of headings) {
	textContent = textContent.trim();

	if (textContent) {
		const indent = "  ".repeat(localName.slice(1) - 2);
		const marker = text.match(/^\d+\. /) ? "" : "- ";
		result += indent + marker + text + "\n"; // 改行追加
	}
}

result = result.trim(); // 最後の改行削除


// Actions

// a. 自動コピー
navigator.clipboard.writeText(result).then(() => alert("目次をコピーしました"));

// b. 自分でコピペしたい場合
prompt("見出し一覧", result);

// c. 確認したいだけの場合
alert(result);
```

セレクタを変更すれば `h2, h3` などにも簡単に絞れます。  
以下のような感じで prompt で対象の要素を確認させたりもできます。  

```js
const headings = document.querySelectorAll(
	prompt("Selector", "h2, h3, h4, h5, h6")
);
```

## Trello のチェックリスト用

Trello で進捗管理したくなったので、マークダウン形式を解除して特定の見出し (デフォルトは h2) だけ抜き出すパターンも用意しました。

```js
javascript:{navigator.clipboard.writeText(Array.from(document.querySelectorAll(prompt("Selector","h2"))).map(({textContent:t})=>((t=t.trim())?t+"\n":"")).join("").trim()).then(()=>alert("見出しをコピーしました"))}
```

結果を Trello のチェックリスト入力欄に貼り付けると、簡単にリスト生成できます。
元のコードも一応。

```js
navigator.clipboard
	.writeText(
		// 主な処理コード 
		Array.from(document.querySelectorAll(prompt("Selector", "h2")))
			.map(({ textContent: t }) => ((t = t.trim()) ? t + "\n" : ""))
			.join("")
			.trim(),
	)
	.then(() => alert("見出しをコピーしました"));
```
業務1年目によく使用したWindowsのショートカットキー

業務1年目に、よく使用し便利だった**Windowsのショートカットキー**をまとめてみます。（中には調べている中で、今後使用したいと思ったものもあります・・・。）

# 環境
* windows11

# Windowsショートカットキー

#### コピー＆ペースト関連　Windowsショートカットキー
<table> 
  <thead>
    <tr>
      <th>動作</th> <th>ショートカットキー</th>
    </tr>
  </thead>
  <tr>
    <td> すべて選択 </td> <td>「Ctrl」＋「A」</td>
  </tr>
  <tr>
    <td> コピー </td> <td>「Ctrl」＋「C」</td>
  </tr>
  <tr>
    <td> 貼り付け </td> <td>「Ctrl」＋「V」</td>
  </tr>
  <tr>
    <td> クリップボードの履歴一覧を表示 </td> <td>「Windowsキー」＋「V」</td>
  </tr>
  <tr>
    <td> 切り取り </td> <td>「Ctrl」＋「X」</td>
  </tr>
    <tr>
    <td> スクリーンショット </td> <td>「Shift」＋「Windowsキー」＋「S」</td>
  </tr>
</table>

#### 画面関連　Windowsショートカットキー
<table> 
  <thead>
    <tr>
      <th>動作</th> <th>ショートカットキー</th>
    </tr>
  </thead>
  <tr>
    <td> 画面ロック </td> <td>「Windowsキー」＋「L」</td>
  </tr>
  <tr>
    <td> エクスプローラーを開く </td> <td>「Win」＋「E」</td>
  </tr>
   <tr>
    <td> 統合アドレスバーにフォーカス移動 </td> <td>「Alt」＋「D」</td>
  </tr>
  <tr>
    <td> エクスプローラーで新しいタブの追加 </td> <td>「Ctrl」＋「T」</td>
  </tr>
  <tr>
    <td> デスクトップやエクスプローラー、ブラウザの画面更新 </td> <td>「F5」</td>
  </tr>
  <tr>
    <td> アプリケーションやウィンドウを選択して表示する </td> <td>「Alt」＋「Tab」</td>
  </tr>
  <tr>
    <td> ウインドウを最大化 </td> <td>「Win」＋「↑」</td>
  </tr>
  <tr>
    <td> ウインドウを縮小表示 </td> <td>「Win」＋「↓」</td>
  </tr>
  <tr>
    <td> ウインドウを左半分に表示 </td> <td>「Win」＋「←」</td>
  </tr>
  <tr>
    <td> ウインドウを右半分に表示 </td> <td>「Win」＋「→」</td>
  </tr>
</table>

#### デスクトップ関連　Windowsショートカットキー
<table> 
  <thead>
    <tr>
      <th>動作</th> <th>ショートカットキー</th>
    </tr>
  </thead>
  <tr>
    <td> デスクトップを表示する </td> <td>「Windowsキー」＋「D」</td>
  </tr>
  <tr>
    <td> 仮想デスクトップを新規作成 </td> <td>「Windows」＋「Ctrl」 + 「D」</td>
  </tr>
  <tr>
    <td> 現在の仮想デスクトップを閉じる </td> <td>「Windows」＋「Ctrl」 + 「F4」</td>
  </tr>
  <tr>
    <td> 右のデスクトップへ移動 </td> <td>「Windows」＋「Ctrl」 + 「→」</td>
  </tr>
  <tr>
    <td> 左のデスクトップへ移動 </td> <td>「Windows」＋「Ctrl」 + 「←」</td>
  </tr>
</table>

#### 文字変換関連　Windowsショートカットキー
<table> 
  <thead>
    <tr>
      <th>動作</th> <th>ショートカットキー</th>
    </tr>
  </thead>
  <tr>
    <td> ひらがなに変換 </td> <td>「F6」</td>
  </tr>
  <tr>
    <td> 全角カタカナに変換 </td> <td>「F7」</td>
  </tr>
  <tr>
    <td> 半角カタカナに変換 </td> <td>「F8」</td>
  </tr>
  <tr>
    <td> 全角英数に変換 </td> <td>「F9」</td>
  </tr>
  <tr>
    <td> 半角英数に変換 </td> <td>「F10」</td>
  </tr>
</table>

#### その他　Windowsショートカットキー
<table> 
  <thead>
    <tr>
      <th>動作</th> <th>ショートカットキー</th>
    </tr>
  </thead>
  <tr>
    <td> 保存 </td> <td>「Ctrl」＋「S」</td>
  </tr>
  <tr>
    <td> 検索 </td> <td>「Ctrl」＋「F」</td>
  </tr>
  <tr>
    <td> 直前の操作を取り消し（undo） </td> <td>「Ctrl」＋「Z」</td>
  </tr>
  <tr>
    <td> 直前の操作を再度実行 (redo) </td> <td>「Ctrl」＋「Y」</td>
  </tr>
  <tr>
    <td> 新しいウインドウを開く </td> <td>「Ctrl」＋「N」</td>
  </tr>
  <tr>
    <td> ウインドウを閉じる </td> <td>「Ctrl」＋「W」</td>
  </tr>
</table>


https://happyhackingkb.com/jp/life/hhkb_life56.html
単体テストと結合テスト

## はじめに

「単体テストって、どこまでなんでしょう？」
という質問を受けました。

社内で新人さん向けにテスト勉強会をした時、うちの会社は単体テストは実装者が、結合テスト以降はテストチームがやることが多いよ、って話をしたので、自分が実装するときにどこまでテストすればいいのか気になったようでした。

* 単体テストでは単一の機能、コンポーネント、モジュールなどに対して個別にテストを行う
* 結合テストでは単体で別々にテストしたものを組み合わせ、適切に連携しているかをテストする

その時はこんな感じで説明してました。
たしかに曖昧だよな、と思ったので自分の中でも整理しなおしてみます。


## 実際のテストケースで考えてみる
例えば、「ログイン機能」について考えてみます。

１）入力値と結果に注目
画面にログインIDとパスワードを入力し、組み合わせがあっていればログインさせるというのは、入力に対して出力を行う一つの機能ととらえることができます。

<img width="450" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316788/bd703825-a342-cd6b-ac2d-ce2932a0b071.png">

* 画面から入力値（ID・パスワード）を受け取る
* ログイン可不可を画面に返す

かなりおおざっぱですが、これをテストケースにするなら最低限以下のようなケースが必要と考えられます。
|ケース|期待結果
|:--|:--|
|IDとパスワードの組み合わせでログインボタンを押下する|ログイン可不可の結果を返す|


２）内部の処理に注目
内部の処理に従って、もう少し細かく分けて考えることもできます。

* 画面から入力値（ID・パスワード）を受け取って変数に入れる
* パスワードをDBに格納されている形式に合わせて暗号化する
* アカウント情報を格納しているDBに接続する
* DBに問い合わせを投げる
* 結果を受け取る
* 結果からログイン可不可を画面に返す

実際にプログラムを書く場合には、２）のように処理を分けていると思いますが、このようにプログラムの関数＝単体と解釈することもできます。

この時の粒度でテストケースを考えると以下のようになります。

| ケース | 期待結果 |
|--|--|
|   画面からの入力値   |   画面からの入力したIDとPWをそれぞれ変数に格納していること   |
|   PWの変換   |   受け取ったPWを暗号化して変数に格納していること   |
|   DB接続   |   アカウント情報を格納しているDBへの接続が成功していること   |
|   DB問い合わせ   |   DBに投げている問い合わせ文が想定しているものであること   |
|    |   　　　　　　　　　　　　　　　　　　　　　　　　････････ 等々   |

このようなケースでは個々の変数に格納されている値をデバッグツールを使って参照したり、実行内容をログに出力してみる、デバッグ用のコードを書くなど、実装の中で何をやっているかを分かったうえでテスト方法を考えてテストすることが必要になるので、実装者自身が行うことが多いです（多いだけでテストチームがやることももちろんあります）。

そしてこの２）のパターンを「単体テスト」と呼び、その後それらをまとめた機能としての動きである１）を「結合テスト」としてテストチームが実施する場合が多いように思います。

ちなみに、実装の中身のロジック等を知ったうえで行うテストを「ホワイトボックステスト」と呼び、中で何をしているかには触れすに入り口と出口だけに注目したテストを「ブラックボックステスト」と呼びます。
なので、

単体テスト　＝　ホワイトボックス　＝　実装者が実施
結合テスト　＝　ブラックボックス　＝　テストチームが実施

みたいに解釈されることがあるんですが、**実際はそうとは限りません**。
（せいぜいそういう傾向が強いかな、くらい）

どこからどこまでを1つの機能（ファンクション・関数）とするかは見方によって変わってきます。そのため単体／結合の分け方や、ホワイトボックス／ブラックボックスのどちらでテストするかは固定的なものではなく、環境や目的によっても変化します。

一応、有名なV字モデルの図では単体テストは詳細設計（コンポーネント設計）をテストベースとするように書かれていますが、詳細設計をどこまで書くか、というのも組織によってブレがあるように思います。

<img width="450px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/316788/f649eba8-9787-2eb9-bf17-ceef0b034263.png" >



# さいごに
結局、どこまでを「単一の機能」として「単体テスト」と呼ぶかについては、はっきりした決まりがあるわけではないのだと思います。

テストする際には、プログラマとテスターが認識をそろえないとな、というコミュニケーション大事、って話に落ち着いてしまいました。（ありがち・・・）


## おまけ
結合テストの後に来るのがシステムテストなわけですが、結合テストが「コンポーネントやモジュールが連携して動くか」というプログラムより？のテストであるのに対して、システムテストはシステムとして要件を満たしているのかどうか、つまり「エンドユーザーの要件にあっているかシステム全体の動きを見る」テスト、ということになります。

システムテストのテストベースが要件定義になっているのはそういうことなんですね。
【MarkdownAI】自分好みのクラフトビールを提案しよう！

# はじめに

この記事は、株式会社スピードリンクジャパン Advent Calendar 2024 の14日目の記事です。

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


こんにちは！社会人１年目の石川です。
まずは、この記事を開いていただきありがとうございます！
今回は「自分に合ったクラフトビールを提案してくれる機能」をMarkdownAIで作ってみたので、その過程を皆さんに共有したいと思います！

# 目次
1. [クラフトビール提案機能を作った理由](#クラフトビール提案機能を作った理由)
3. [機能の説明](#機能の説明)
3. [実際に作成したサイト](#実際に作成したサイト)
4. [実装の詳細](#実装の詳細)
4. [実際の検索結果](#実際の検索結果)
6. [まとめ](#まとめ)

# クラフトビール提案機能を作った理由

私は大学時代、桑の実を使ったビールの醸造を研究していました。その中で、わずかな材料の違いがビールの風味や香りを大きく変えることに感動し、クラフトビールの奥深さに魅了されました。

そこで、AIを活用して、ユーザーの好みやその日の気分に合ったクラフトビールを提案できる仕組みを作ろうと考えました。

最後まで読んでいただければ幸いです。

# 機能の説明
今回作成したサイトはビールの特徴（苦味、甘味、香り）とユーザーの好みをマッチングし、好みに合ったビールを提供してくれます。

この提案機能は、以下のステップで動作します。

1. **好みを入力**  
   苦味、甘味、香りの3項目を1〜10のスケールで入力します。
2. **提案結果の表示**  
   ボタンを押すと、AIがあなたの好みに基づいておすすめのビールを提案します。結果にはビールの種類と特徴が表示されます。

# 実際に作成したサイト
実際に作成したサイトは以下から見ることができるのでぜひ試してみてください！

https://mdown.ai/content/6dee7eec-fed8-4ad6-84ed-2a5aebdeaadb

# 実装の詳細
作成方法は以下の記事に詳しく書いてあったのでそちらをご参考にしてください。

https://qiita.com/mdown_ai_jpn/items/d3e281565c876a0bd64f#%E5%AE%9F%E9%9A%9B%E3%81%AB%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86ai%E5%88%B6%E4%BD%9C%E6%89%8B%E9%A0%86

今回私がAIに渡したプロンプトは以下の通りです。

```
ユーザーが「苦味:7」「甘味:5」「香り:8」のように入力した場合、それに合ったクラフトビールを提案してください。
回答は以下の形式で返してください：
1. ビールの種類（例: IPA）
2. その特徴（例: ホップの風味がしっかりしていて、フルーティな香りが楽しめる）
```

# 実際の検索結果
今回私の好みのビールを「苦味:7 甘味:5 香り:8」と入力して生成しました。ビールは少し苦味がある方が好きなので苦味は7、バランスも大事なので甘味は控えめに5、香りはしっかり楽しみたいという気持ちで8を設定しました。

![スクリーンショット 2024-12-12 11.20.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3787308/48afdc55-4470-4718-2f44-0072c4e95660.png)

結果はダブルIPAというビールでした。このビールは飲んだことがないのですが、ホップの香りが強いと聞いたことがあります。生成結果にもとても興味深い香りの特徴が書いてあるので今度試してみたいです！

# まとめ
本記事では、MarkdownAIを使ってクラフトビールの提案サイトを作成しましたが、簡単に実装できたことに驚いています。

今後の改良案として、次のような機能も作ってみたいと思いました！
- 季節や地域に合わせたビール提案
- ユーザーが過去に試したビールの履歴を記録する機能

ぜひ、この記事を参考に皆さんもMarkdownAIを使ったサイト作りに挑戦してみてください！
最後まで読んでいただきありがとうございました！
reloadのコマンドが動かないんだけど！？

って検索した人がこれを見つけますように。

:::note warn
Java Edition 1.21.3時点のお話です。
:::

# 問題
```ruby:reload.mcfunction
say reloaded
scoreboard players add $login BOARD 1
```
`/reload`コマンドを打つときは実行されるのに、ワールドを出て入りなおしたときには実行されない！

# 解決策
```ruby:reload.mcfunction
function namespace:detect
```
```ruby:namespace:detect
execute if entity @e[type=!player] run function namespace:enter
execute unless entity @e[type=!player] run schedule function namespace:detect 1t
```
```ruby:namespace:enter
say reloaded
scoreboard players add $login BOARD 1
```
これらの関数を作りましょう。`namespace`は自身のデータパックフォルダの名前を入れてください。`data`フォルダの下にある、`minecraft`と同じ場所にあるやつです。
以上で実装は終了です。お疲れ様でした。

# 挨拶
どうもおはしあ。けいらぎっていいます。今回は最近自分が陥った問題について。`reload.`に入れたコマンドのうち、動くものと動かないものがあって困っていました。それについてちょっと考察してみましょう。

# 原因
あくまで検証と予測の範疇ですが、ワールドを開いた時のコンテンツの配置に順序があると思われます。

順番：**ブロック** ⇒ **`reload.mcfunction`** ⇒ **プレイヤー** ⇒ **その他のエンティティ**

世界に入る前、ゲームがエンティティを配置する前に`reload.`が実行されています。これはMinecraftのログ(game output)を見るとわかりますが、プレイヤーが世界へ入る前にコマンドが実行されたというログが流れていました。
これ、`/scoreboard`の仮想エンティティ($入りの名前)も反応しないのでちょっと面倒です。
# 対策
つまりはエンティティが読み込まれるまで繰り返し検知させましょう。
```ruby:namespace:detect
... unless entity @e[type=!player] run ...
```
ifの逆であるunlessを用いて、「エンティティがいなければ実行」という条件を付けてループさせます。検知対象が`@e[type=!player]`なのは、他のエンティティよりプレイヤーの読み込みの方がちょっと早いからですね。「プレイヤーだけ検知できれば良い」というときは`@a`で良いと思います。
```ruby:namespace:detect
... run schedule function namespace:detect 1t
```
以降の文で、この関数を1tick後に予約しておきましょう。これでエンティティが読み込まれるまで検知され続けます。
# `/schedule`について
```ruby:構文
/schedule function <関数のファイル> <時間> [append|replace]
```
指定した時間に、関数を**予約**しておくことができるコマンドです。`<時間>`の数字と文字から、実行したい時間を細かく指定できます。
|単位|意味|時間|
|:-:|:-:|:-:|
| 1t |tick|1/20秒|
| 1s |second|1秒|
| 1d |day|20分|

`[append|replace]`は、同じ関数を複数予約したときの挙動が変わります。`append`は予約した分だけ順番に実行されますが、`replace`は最後に予約した一回で他の予約が上書きされます。何も入力しなければ`replace`となります。
### 注意点
予約した関数は、ワールド全体として実行されます。つまり`@p`を使うと違う方向からの指定になり、`~ ~ ~`を使えば実行座標は行方不明です。~~どこなんだよここは...~~
なので予約した関数の中では、`execute at`や`positioned`を使って実行場所を指定してあげましょう。
また、ワールドを出ると予約していた関数は**消滅**します。`reload`で再予約する必要がありますね。
**追記**：`/reload`や`/schedule`の実行位置は初期スポーン地点とのことでした。情報ありがとうございます！
# 終わり
てことで今回は`reload`とエンティティの関係についてでした。
質問や改善点などあればお気軽にどうぞ！できれば優しく、フランクな感じで。
自分の苦労が誰かの助けになれば幸いです。
それでは、ご覧いただきありがとうございました。
おつなも！
244日目 情報セキュリティマネジメント試験に合格した時の学習法by社畜S

## :checkered_flag:はじめに
こんにちは、社畜Sです。
今回もタイトル通り
**情報セキュリティマネジメント試験**（以下SG）
に合格したときの学習法をまとめていこうと思います。

また、当時は基本情報技術者試験とも同時進行でも学習を進めていたので、基本情報と比べての難易度も書いていこうと思います。
どちらを受けるか悩んでいる方は参考にしていただければ幸いです。
## :checkered_flag:社畜Sのスペック（SG受験時版）<br> 
> 所持資格➡ITパスポートのみ取得。基本情報不合格（１回）。あんまり関係はないが、MOS（PowerPoint、Excel）も取得していた。
> ITについての知識➡ITパスポートの勉強と専門学校での学習でちょっとだけ自信がついてきた時期。

当時の社畜Sのスペックはこのような感じでした。
基本情報技術者試験にぎりぎりで落ちてしまい、次は絶対合格してやるぞ！と意気込んでいる際に、担任から「基本情報、過去問解いてるとこ見てる感じは行けそうだし、SGもついでに受けたら？」といわれ、なし崩し的に基本情報受験1週間後くらいにSGも受験することになりました。
当時は無理だと思っていましたが、やってみると意外と何とかなります。
## :checkered_flag:こういう勉強してました
### とりあえず[セキュリティマネジメント試験ドットコム](URL "https://www.sg-siken.com/")をやれ！！！！！！！！

IPA系の試験の時に毎回書いている気がしますが、とにかくSG試験ドットコムを使用することをおすすめします。
400問以上の過去問を解けることに加えて、650問の予想問題もついてきます。しかも全問無料かつ分かりやすい解説付き！！！
他にも統計情報だったり、おすすめテキストだったり…いろんな情報がこのサイト1つでわかるので、使わないのは損レベルでおすすめです

SG受験時の学習法としては
①基本情報の学習を通して基礎知識を付ける
②空いた時間にひたすらSG試験ドットコムで過去問を解きまくる

この流れで学習していました。
基本情報と並行しながらの学習だったため、基礎知識をつけるのは基本情報の学習に任せ、SG試験ドットコムは全問暗記するくらいの勢いで過去問を解き続けました。
テキストは購入していません。

問題難易度としては基本情報というよりはITパスポート側に近いので、基本情報、もしくはITパスポートを学習している人であればかなりとっつきやすい試験だと思います。
## :checkered_flag:基本情報技術者試験、ITパスポートと比べて
個人的な難易度は
**基本情報＞＞ITパスポート≧SG試験**
の順に難しかったと思います
基本情報技術者試験が一つ抜けて難易度が高く、ITパスポートとSG試験が同じくらいの難易度だと感じました。
ドットコムのほうで集計されていた令和3年度の合格率を見ても
> 基本情報：40％
> SG試験：52％
> ITパスポート：52％

となっていたので、統計的に見てもITパスポートとSG試験の難易度は同じくらいだと思います。

私がSG試験のほうが簡単に感じたのは、既にITパスポートを取っていたのと、基本情報の学習も進めていたからというのも大きいと思うので、どういう順番で試験を受けるかは結構個人差が出そうです。
人によっては1発目から基本情報を受けてみるのも良いかもしれません。

## :checkered_flag:まとめ
というわけで、今回は情報セキュリティマネジメント試験に合格した時の学習法についてまとめてみました。
この記事が、これからセキュリティマネジメント試験を受験する人の助けに少しでもなれば幸いです。

もうすぐ応用情報技術者試験の結果も出ます。
資格勉強は大変だと思いますが、一緒に頑張りましょう！
## :checkered_flag:余談
社畜Sの過去の合格体験記です。良ければこちらもぜひ…

https://qiita.com/QiiTaro_/items/4ec66dae7f8d2ece565e

https://qiita.com/QiiTaro_/items/a82c3d9ece972f386f89

https://qiita.com/QiiTaro_/items/aa6b0e67c7315e817315
ノートパソコンのタッチパッドを小さくする方法

こちらの記事は[一関高専 Advent Calendar 2024](https://adventar.org/calendars/10592)の2日目の記事です。

皆さん、ノートパソコンのタッチパッドが無駄に大きくて困ったことありませんか？

私が最近買ったノートパソコンはタッチパッドが気持ち大きめサイズで、文字入力中に親指の付け根あたりで触ってしまい、カーソルがどこかに飛んでいくという事態が多発してしまいました。

そこで今回はこのタッチパッドの調整方法、特に「反応する範囲を変える」ということについて記事にしたいと思います。


## 注意事項
**レジストリを編集する必要がある**ため必ず**バックアップ**を取った上で、**自己責任**での作業をお願いします。

## 環境
- OS: Windows11
- 本体: ThinkBook 14 Gen 6 (AMD)

## やり方

といっても、やり方自体は簡単です。

### レジストリエディタを開く

まずはレジストリエディタを開きます。

1. win+rを押す
1. `regedit`と入力しEnter
1. 「はい」を押す

### パスを入力する

次に上部のパス入力欄に対して次のレジストリへのパスを入力する

`HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\PrecisionTouchPad`

### 値の追加 

ここでパラメータを入力して範囲を調整します。
以下に例として「タッチパッドの左側1cmを反応しない領域にする」という設定方法を示します。


1. 右にあるレジストリ一覧の何も無いところで　右クリック->新規->DWORD を選択
1. 値の名前を`SuperCurtainLeft`にする
1. 追加した値をダブルクリック
1. 表記を10進数にする
1. 値のデータの部分に1000を入力する
1. OKをクリック

### 本体を再起動する

レジストリの編集が終わったら、PC本体を再起動をしてください

## 他の値

先程の例では`SuperCurtainLeft`という値を追加しましたが、他にもRightやTop、Bottomも存在しています。

また、今回は手がぶつかって反応してしまうという問題に対処するため、触っても反応しなくなる`SuperCurtain`を追加しましたが、更に細かい調整がしたい場合は公式のドキュメントが非常に参考になるのでそちらを参照してください！


## 参考にしたサイト

[高精度タッチパッドのチューニング マイクロソフト公式ドキュメント](https://learn.microsoft.com/ja-jp/windows-hardware/design/component-guidelines/touchpad-tuning-guidelines)
Nuxt3 pagesの表示方法（環境構築からHello Worldまで）

# 概要
`Nuxt`を起動し、画面に`Hello World`を表示させるまでの手順になります。

### 補足
画面である`Vue`の`views`ディレクトリは`Nuxt`では`pages`ディレクトリに相当します。
ルーティングを設定する際、`Vue`では`router/index.js`に記載する必要がありましたが、`Nuxt`では`pages`にファイルを作成すると、自動でルーティングも設定されます。

# 環境構築
※windowsのpowershellで行っています。

まずはNode.jsバージョン18以上がインストールされているか確認
```powershell
node -v

# v20.17.0などが表示されればok
```

Nuxt.jsをインストール(今回はバージョン3.14)
```powershell
npx nuxi@3.14 init my-nuxt-project
```

プロジェクトディレクトリに移動し、開発サーバー起動、表示されたURLをブラウザで開きます。
```powershell
cd my-nuxt-project
npm run dev
```

# コード修正

まずは、pagesディレクトリを作成し、testsディレクトリにHelloWorldコンポーネントを作成します。
```vue:./pages/tests/HelloWorld.vue
<template>
  <div>
    <h1>Hello Nuxt3!</h1>
  </div>
</template>
```

次に、pages配下にindex.vueを作成し、HelloWorldコンポーネントを読み込み、表示させます。
```vue:./pages/index.vue
<script setup>
import HellowWorld from "./tests/HellowWorld.vue";
</script>

<template>
  <p>テストです。</p>
  <HellowWorld />
</template>
```

最後に、ルートディレクトリの`app.vue`に、`<RouterView />`をラップした`<NuxtPage />`を記載し、`pages/index.vue`を表示させます。
```vue:./app.vue
<template>
  <div>
    <NuxtPage />
  </div>
</template>
```
以下のような画面が表示されるはずです。
![スクリーンショット 2024-12-10 155312.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940986/ac0212de-8dbf-cdb2-a582-acfd9001bdc6.png)

# 注意点
```vue
<NuxtPage />
```
を使う場合は、`pages/index.vue`を作成する必要があります。
axiosで共通のヘッダーを付与する方法

# 概要
axiosを使ってHTTP通信を送る時、認証トークンなどを共通でヘッダーに付与させたい場合、リクエストインターセプターを使います。

# コード例
以下は、HTTPリクエストに、認証トークンを保持する`Authorization`ヘッダーを共通で付与する例です。

```typescript:axios.ts
import axios from "axios";
import type { InternalAxiosRequestConfig } from "axios";

const axiosInstance = axios.create({
  baseURL: "http://localhost:5173/", // ベースURLを設定
  withCredentials: false
});

// リクエストインターセプターを追加
axiosInstance.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const token = "jwtの認証トークンなど";
    // リクエストヘッダーに含める
    config.headers["Authorization"] = `Bearer ${token}`;

    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

export default axiosInstance;
```
上記をインポートし、
```typescript
import axiosInstance from "@/axios";

axiosInstance.post(endpoint);
```
のように使います。

# 詳細
リクエストインターセプターを使うことで、リクエストが送信される前に処理を挟むことが出来るようです。
これでどのリクエストにも`Authorization`ヘッダーが付与された状態になりました。

※Cookieを付与させたい場合は、`axios.create`の箇所で`withCredentials: true`にする。

※上手くいかない場合は、backend側の`CORS`許可の設定を確認する必要があるかもしれません。

# 補足
レスポンスインターセプター(サーバーからのレスポンスが返される前に処理を挟むことができる)もあるみたいです。
通常のcronとAWSのcronの違いにハマったのでメモ

## はじめに
通常のcronから、AWS(EventBridge)に移行し、その際のcronにハマったのでメモ

## 通常のcron
``` :cron
0 2 2 * *
```
- フィールド数: 5つ
- フィールドの順序: 分、時、日、月、曜日
- 書式例: 00 2 2 * *  #(0分 2時 2日 すべての月 すべての曜日)
- 曜日表記: 0-7（0と7は日曜日）
- タイムゾーン: システムのローカルタイム

## AWSのcron
``` :aws_cron
cron(0 2 2 * ? *)
```
- フィールド数: 6つ
- フィールドの順序: 分、時、日、月、曜日、年
- 書式例: cron(0 2 2 * ? *)  #cron(0分 2時 2日 すべての月 全ての曜日 すべての年)
- 特殊文字:
    - ?を使用（日と曜日が同時に指定できない）
- タイムゾーン: デフォルトでUTC
- 曜日表記: 1-7（1は日曜日）
[Rust]コレクション型とイテレーターの活用

## 配列

同じ型の固定長の要素数を持つ型です。一度宣言するとサイズは変えられません。そのため、宣言時にサイズがわかっているケースで利用します。型定義は`[型; サイズ]`で行います。

### 宣言

```rust
let arr: [i32; 3] = [1, 2, 3];
```

### 参照

```rust
println!("{}", arr[0]); // 1
```

:::note warn
他の言語と同様、サイズを超えたインデックスを与えるとプログラムは異常終了（パニック）します。
:::

:::note
配列は宣言時に要素の型とサイズがわかっているので、トータルで必要なメモリサイズが計算できます。そのためデータはスタックに格納され、アクセスが高速になります。
:::
　
## タプル

固定長で複数の値をまとめあげる点では配列と似ていますが、各要素の型は必ずしも一致している必要はありません。

### 宣言

```rust
let tup: (i32, f64, &str) = (42, 3.14, "hello");
```

### 参照

```rust
println!("{}", tup.0); // 42
println!("{}", tup.1); // 3.14
println!("{}", tup.2); // hello
```

## ベクタ

同じ型の可変長の要素を持ちます。配列と違い、宣言後に要素を追加したり削除したりできます。配列よりは低速度ですが、コレクションのサイズを柔軟に変えたい場合はベクタを使用します。

### 宣言

`Vec::new`を使う方法と`vec!`を使う方法があります。どちらも結果は同じです。

```rust
let mut vec1: Vec<i32> = Vec::new();
vec1.push(1);
vec1.push(2);

let vec2 = vec![3, 4, 5];
```

### 参照

`[]`の中にインデックスを指定する方法と`get`メソッドを使う方法があります。前者は配列同様パニックを起こす可能性がありますが、後者は`Option`を返すのでその恐れはありません。

```rust
println!("{}", vec2[0]); // 3
if let Some(value) = vec2.get(1) {
    println!("{}", value); // 4
}
```

### 更新

`push`や`pop`など、用途に応じたメソッドが利用できます。

```rust
vec1.push(6);
vec1.pop();
```

## スライス

スライスはコレクションそのものではなく、あるコレクションの一部への参照を持つ変数です。すでに何かしらのコレクション（例えば配列）があったとして、そのコレクションの一部（全部も可能）を参照する形で宣言されます。
宣言時は`&コレクション名[範囲]`の形で指定します。

```rust
let arr: [i32; 3] = [1, 2, 3];

let slice = &arr[0..2]; // [1, 2]
println!("{:?}", slice);
```

### 文字列スライス

スライスは様々なコレクションに対して作成でき、文字列もその対象です。文字列は`&str`型として扱えるため、文字列の一部分を参照する場合は`&str`に対するスライスを利用できます。

```rust
let s = "hello world";
let hello = &s[0..5];
let world = &s[6..];
println!("{}, {}", hello, world); // hello, world
```

ただし、このスライスの1要素はバイト単位であるため、マルチバイト文字を含む場合は「1要素=1文字」とは限りません。そのようなケースを想定するのであれば、`for`文などを使って処理しましょう。

## コレクションのまとめ

今回取り上げたコレクションの違いをまとめてみます。

| 種類 | 要素の型 | サイズ |
| - | - | - |
| 配列 | すべて同じ | 固定 |
| タプル | バラバラでもOK | 固定 |
| ベクタ | すべて同じ | 可変 |

:::note
固定長と可変長で明確に分けているのでその点に注意しましょう。基本的にはベクタのほうが出番が多そうなイメージです。
TypeScriptのオブジェクトのように違う意味を持つ値をまとめて扱いたいが、それぞれに名前をつけるほどではない、みたいなケースでタプルが活用できそうです（TypeScriptにもタプルがありますが、そうやって使うイメージ）。
:::

## `for`文で使うには

### 配列

そのままでは使えないので、参照を渡すか`iter`メソッドを利用しましょう。

```rust
for val in &arr {
    println!("{}", val);
}
```

### タプル

`iter`メソッドを利用します。

```rust
let tuples = [(1, "one"), (2, "two")];
for (num, word) in tuples.iter() {
    println!("{}: {}", num, word);
}
```

### ベクタ

そのまま`for`文で使えますが、所有権が移動してしまうので、参照を渡しましょう。

```rust
for val in &vec2 {
    println!("{}", val);
}
```

## 様々なメソッド

コレクション（正確に言えば`Iterator`トレイトを実装している型）にはいくつかのメソッドが用意されています。
そのうちの主なものを紹介します。

### `map`

```rust
let vec2 = vec![3, 4, 5];

let doubled: Vec<i32> = vec2.iter().map(|x| x * 2).collect();
println!("{:?}", doubled); // [6, 8, 10]
```

### `filter`

```rust
let vec2 = vec![3, 4, 5];

let evens: Vec<i32> = vec2.iter().filter(|&&x| x % 2 == 0).cloned().collect();
println!("{:?}", evens); // [4]
```

### `fold`

```rust
let vec2 = vec![3, 4, 5];

let sum: i32 = vec2.iter().fold(0, |acc, &x| acc + x);
println!("{}", sum); // 12
```

:::note
このあたりはTypeScriptと似ていますね（`reduce`がRustでは`fold`になる？）。やはりコレクションから使えるメソッドは慣れると直感的に書けて筆者は好きです。
:::
外部のシステムにコールアウトしてオブジェクトを更新するApexクラスを複数件対応にする

**使っているクラウドなどの小ネタ Advent Calendar 2024 19日目**


画面のボタンからApexのクラスをコールするようにして実行すると問題なく機能します。
ただし、Apexバッチに組み込んで使うと下記のエラーになります。

:::note alert
You have uncommitted work pending. Please commit or rollback before calling out
:::

まさにここで解説されているとおりの内容

>なんのための制限かわかりませんが、(コールアウト実行 → 結果をリストやマップなどに保持)を繰り返す → レコード更新 とする必要があります。

+ [Salesforce で You have uncommitted work pending エラー](https://www.venture-net.co.jp/engineer/18483/)

# 最終的な対応

バッチ処理で使えるように一括処理を考慮したコードに書き直しました。

```Java
public static String calljobcan_org2(List<Jobcan053__c> j53List) {
        if (j53List == null) return '';
        
        Map<String,String> saveBodyMap = new Map<String,String>();
        for (jobcan053__c j53 : j53List){
            String stBody = callout_org(j53);//ここでコールアウトさせて、Jsonを得る
            saveBodyMap.put(j53.Id,stBody);//Mapに保存する
        }
        
        List<Jobcan053__c> updateJ53List = new List<Jobcan053__c>();
        for (jobcan053__c j53 : j53List){
            
            String stBody = saveBodyMap.get(j53.Id);
            if (stBody != null) {
                //Jsonを使ってオブジェクトに値をセットする
                Jobcan053__c j53new = createJobcan053(j53.Id,stBody);
                updateJ53List.add(j53new);//結果はListに保存する
            }
            
            if (updateJ53List.size() >0) update updateJ53List;//一括更新
            
        }
        
        return '';
    }    
```

別の処理でも同じです。コールアウト結果も変数に入れて後でまとめて判断してDML操作を行います。
コールアウト⇒DML⇒コールアウトではエラーになります。

```Java
/**
	 * 複数件処理する。バッチからの起動用
     */  
    public static List<Jobcan053__c> calljobcan_org2(List<Jobcan053__c> j53List) {
        List<Map<String,Object>> RetMapList = new List<Map<String,Object>>();
        List<Jobcan053__c> updateJ53List = new List<Jobcan053__c>();
        if (j53List == null) return updateJ53List;        
        
        for (jobcan053__c j53 : j53List){
            Map<String,Object>  RetMap = new Map<String,Object>();
            RetMap = jobcan_callout5.callout_org3(j53);
            RetMapList.add(RetMap);
        }   
        
        for (Map<String,Object> rm : RetMapList) {
            if ((Integer)rm.get('StatusCode') == 200){
                Jobcan053__c j53n = new Jobcan053__c();
                j53n.Id = (String)rm.get('Id');
                j53n.isTask__c = true;
                updateJ53List.add(j53n);
            }
        }
        system.debug(Logginglevel.INFO,'size===> '+ updateJ53List.size());
        //if (updateJ53List.size() >0 ) update updateJ53List;

        return updateJ53List;
    }    
```
KinoBenchee で性能比較を視覚化する

## はじめに

昨年 2023 年 12 月、 WIP　の時点で紹介していた KinoBenchee が正式にリリースされていたので、改めて紹介します

https://qiita.com/RyoWakabayashi/items/afbd4d2187368346d5a9

https://github.com/livebook-dev/kino_benchee

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

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/kino/kino_benchee.livemd

## Benchee とは

Benchee は Elixir でベンチマークするためのモジュールです

処理のパフォーマンス比較が簡単にできます

https://github.com/bencheeorg/benchee

KinoBenchee を入れておくと、Benchee を実行した際、自動的に結果を表とグラフで視覚化してくれます

## セットアップ

Livebook のセットアップセルでインストールします

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

## ベンチマークの実行例

以下の記事で紹介している「整数の桁数を取得する処理」の2種類を比較してみます

https://qiita.com/RyoWakabayashi/private/194addd1d49b569513d4

まず、比較したい処理を定義します

```elixir
defmodule Digits do
  def count_by_integer_digits(n) do
    n |> Integer.digits() |> length()
  end

  def count_by_common_logarithm(n) do
    n |> :math.log10() |> ceil()
  end
end
```

どちらも整数の桁数を取得する処理なので、同じ入力に対して同じ出力になります

`Integer.digits` を使う実装

```elixir
Digits.count_by_integer_digits(123)
```

実行結果

```elixir
3
```

常用対数を使う実装

```elixir
Digits.count_by_common_logarithm(123)
```

実行結果

```elixir
3
```

二つの処理性能を比較します

```elixir
defmodule MyBenchmark do
  def run() do  
    Benchee.run(
      %{
        "Integer.digits" => fn -> Digits.count_by_integer_digits(123456789) end,
        ":math.log10" => fn -> Digits.count_by_common_logarithm(123456789) end
      },
      memory_time: 2,
      reduction_time: 2
    )
  end
end

MyBenchmark.run()
```

実行結果

![kino_benchee.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/9804d726-15d1-791b-3bf5-7b96c6d22452.gif)

1 秒あたりの実行回数、メモリ使用量、リダクション（内部的な処理量）のタブにそれぞれの比較表、棒グラフが表示されています

1 秒あたりの実行回数を比較すると、常用対数を使ったほうが 2 倍近く速いことが分かります

![runtime.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/e6fcee64-2af5-f046-2789-510bf145fa55.png)

メモリ資料量は更に差が明確で、常用対数の方が 9 倍メモリ効率が良いです

![memory.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/154213fe-dfff-7769-f31f-f939bdd5bda5.png)

内部的な処理量も 6.5 倍の差があります

![reduction.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f75a5747-6153-b437-ff75-44502133bb80.png)

整数の桁数を取得したい場合、常用対数を使った方が圧倒的に速く軽いことが明確に分かります

## まとめ

KinoBenchee をインストールしておくことで、特別なコードを書く必要なく、Benchee を実行すれば勝手に結果が視覚化されます

グラフが出ることで、はっきりとどれくらいの差があるのか分かりますね
/etc/hostsとDNSについて歴史から調べてみた

## /etc/hosts ファイルとは

ホスト名とIPアドレスと対応させるためのファイル

```bash
##
# Host Database
#
# localhost is used to configure the loopback interface
# when the system is booting.  Do not change this entry.
##
127.0.0.1    localhost
255.255.255.255    broadcasthost
::1             localhost
```

ローカルで`/etc/hosts`ファイルを確認するとこの様になっており、`localhost`と`broadcasthost`が設定されていました。

ここで`127.0.0.1f`（IPv4）と`::1`（IPv6）に対し`localhost`を対応させているため、自分のPCにアクセスできる様になっています。

要するに自分のPCで使えるDNSサーバの様な役割ということですね。

hostsファイルについて調べていたら歴史について出てきたので、少し深掘りして簡単にまとめました。

## hostsファイルとDNSの歴史

`hosts` ファイルは元々DNSサーバーの役割をしていたらしい！

まだインターネットが今の様に普及されておらずDNSという概念もない頃、IPアドレスで特定のサーバーにアクセスする必要がありました。

それを解決するために、サイトがIPアドレスに対応したホスト名を定義した `HOSTS.TXT` を提供しており、それを自分のPCの `/etc/hosts` ファイルに保存していました。

これによりホスト名を指定すればアクセスしたいサーバーにアクセスできるため使い勝手が大幅に向上しました。

しかし初めは各サイトがそれぞれの `HOSTS.TXT` を提供してたため、ユーザーは複数のホストファイルをコピーする必要があり非効率でした。

そこで`Stanford Research Institute（SRI）のNetwork Information Center（NIC）`略して `SRI-NIC` というホストで `HOSTS.TXT` ファイルを１箇所で集中管理することにしました。

これにより１箇所から `HOSTS.TXT` をダウンロード（FTPで取得）すればいいので1973年〜1983年頃まではうまく機能していた様です。

しかし集中管理にも問題が出てきました。

初めは数百台しか無かったホストもネットワークが普及していくにつれてホスト数は膨大になり1983年頃には数万台になったため、ホストファイルは大きくなりすぎてしまいました。

データ量が大きいのでネットワーク回線もすぐに一杯になったり、変更も頻繁に行われるため、最新の状態になっておらずエラーが発生したりと、問題点が多く出てきて成り立たなくなってしまいました。

そこで出た解決策が `Domain Name System（DNS）` です。

`HOSTS.TXT` で管理していた問題を以下のように解決しています。

- 「分散管理する」
    - `HOSTS.TXT` では１箇所で管理していたため管理しているホストの負荷が高くサーバーがダウンしていた
    - `DNS`では複数のサーバーで管理しているため、負荷を分散できる（一番上位のルートサーバーは13組）
- 「ホスト名を階層構造で管理する」
    - `HOSTS.TXT`ではデータが増えすぎてホスト名管理が難しくなり、重複する問題があった
    - `DNS`では「.」ドットでドメイン名を区切って名前空間を管理して重複を防ぐことができる
- 「常に最新の情報」
    - `HOSTS.TXT`ではタイムラグなどが発生しエラー原因になっていた。
    - `DNS` では分散環境下でも以下の様な仕組みで整合性のとれた情報が取得できる様にしている。
        - TTL（Time To Live）による期限付きキャッシュ
        - ゾーン転送による定期的な同期
        - DHCPなどからの動的な更新
        - シリアル番号による更新管理

これによりインターネットでの名前解決で `/etc/hosts`ファイルではなく `DNS` が使われる様になりました。

## /etc/hosts の使い道

### ローカル環境でのテスト

- 例えば `127.0.0.1 example.com` と設定して開発サーバーにアクセスするなど

### アクセスを制御する

- 広告サーバーのドメインなどを127.0.0.1に向けることで広告をブロックする
- 特定のドメインにアクセスできない様にする

### 内部システムでの名前解決

- 社内限定のサーバーに対してプライベートな名前解決をする
- DNSを必要としない様な小規模ネットワークでの運用

上記の様な使い道があると思いますが、基本的にDNSよりも先に`/etc/hosts` を参照するので、誤って実在するホスト名を記述していたりしたら想定外のIPアドレスへアクセスしてしまう可能性があるので、注意する必要があります。また、セキュリティの観点から、定期的にhostsファイルの内容を確認し、不正な変更がないかをチェックすることが推奨されます。
「プロパティ」って 何となく使いがちだけど 言語ごとに少し違うよーって話

## はじめに

みなさんはプログラミング言語で「プロパティ」という言葉をよく耳にすると思います。
しかし、プロパティの意味や使い方は言語ごとに異なることがあります。この記事では、プロパティの基本的な概念と、いくつかの主要なプログラミング言語におけるプロパティの使い方について詳しく説明します。

## プロパティとは

プロパティは、オブジェクトの状態や属性を表すためのメンバーです。
対象が、どの様な情報を持っているかを表すために使用されます。

ただ、プロパティという言葉は、プログラミング言語によって微妙に異なる意味を持つことがあるので、説明していきます。

### JavaScript

JavaScript では、オブジェクトのプロパティはキーと値のペアとして定義されます。プロパティはオブジェクトリテラルやクラスを使用して定義できます。

```javascript
const person = {
  name: "qiitaro", // この key value のセットがプロパティ
  age: 30,
};
```

### CSS

MDN には以下の様に説明されています。

> CSS プロパティは、関連付けられた値によりブラウザーがどのように要素を表示するかを定義する特性（色など）です。
> ref:https://developer.mozilla.org/ja/docs/Glossary/Property/CSS

ここだけ見てもわかりませんが、説明されるコードを見ると **キー** がプロパティになることがわかると思います

>MDN より引用
```css
/* "div" はドキュメント中の全ての div 要素が */
/* このルールによってスタイルを整えることを示すセレクターです。*/
div {
  /* 値 "black" を持つプロパティ "color" は、*/
  /* テキストの色が黒くなることを示します。*/
  color: black;

  /* 値 "white" を持つプロパティ "background-color" は、*/
  /* 要素の背景色が白くなることを示します。 */
  background-color: white;
}
```

### PHP
PHPマニュアルでは、クラスのメンバ変数のことを プロパティと呼んでいます。
以下のコードを見て把握してみてください。

```php
<?php
class Person {
    public $name; // パブリックプロパティ
    protected $age; // プロテクテッドプロパティ
    private $email; // プライベートプロパティ
}
```

## 終わりに
いかがでしたでしょうか。
プロパティはプログラミング言語によって少し指しているものが異なる場合があるので、注意が必要です。

特にCSSは属性を指してJavaScriptではキーバリューのペアを指している場合が多いので、混同しないように注意しましょう。

この記事が皆さんの参考になれば幸いです。

## 参考文献

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/ja/docs/Web/CSS/Reference

https://developer.mozilla.org/ja/docs/Glossary/Property/CSS

https://www.php.net/manual/ja/language.oop5.properties.php
Billingに定義された権限

# はじめに
こちらの記事は下記Advent Calendar 2024で紹介しているIBM Cloud権限設定における `Billing` になります。

https://qiita.com/katahiro/items/274bec5ad4a9e2604dcf

# Billingで指定可能な権限のアクセス範囲
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/46344e06-f5f7-d949-e318-2c180ae94ced.png)
- リソース・グループ
- リソース・タイプ

## リソース・グループの指定
これまでの権限設定の場合、設定したリソース・グループに対する情報取得や、インスタンスの作成といった権限が付与されていたのですが、設定してみたところ機能していません…
特定のリソース・グループにのみ権限を設定してみても、他のリソース・グループの請求情報もまとめて参照できてしまいます。バグなのか・・・

## リソース・タイプ
こちらも選択肢として出てきますが実際として利用できない設定になります。
下記添付のように `すべてのリソース・タイプ` しか指定できないため、特定の情報を指定できない状況です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/20e474ef-ba58-704d-cf61-f9500b832c26.png)

# Billingに設定された権限
Billingにはサービス固有の権限が無いため、基本的に下記権限共通部分の記事で触れた部分がベースとなります。

https://qiita.com/katahiro/items/b5e367666fe984944d4b

また下記のようにプラットフォーム・アクセスの設定のみ存在し、サービス・アクセスの権限設定が無い点にご注意ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/4fe57161-ccb3-d292-cea1-57548c86ae3a.png)

## プラットフォーム・アクセスの権限
基本的にViewer以上の権限を与えると請求に関する情報は一通り参照可能になります。

注意点として、請求に関する情報をObject StorageのBucketに保管する機能があります。
この機能の設定を実施する際は、Editor以上の権限が必要になります。(Object Storageに対する権限も必要になります)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/6643b426-abff-9241-9d58-8ec50da46a2a.png)

同様に利用状況が閾値を超えると通知を送る仕組みがありますが、この設定の有効化や閾値の変更、通知先の変更といった編集もEditor以上の権限が必要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/651598/8756f290-0329-935f-ec0c-c6cafbca5c62.png)

# さいごに
Billingとして個別に設定されている権限はありませんが、請求に関する設定の部分はEditor以上の権限が必要なのでご注意ください。

リソース・グループの指定があるにも関わらず、全てのリソース・グループの請求が見えてしまうのはバグなのかなぁ・・・
スプレッドシートでブックマーク管理を実現するChrome拡張機能を作った話

[PONOS Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ponos)の18日目の記事です。
前回は[@iixd_pog](https://qiita.com/iixd_pog)さんでした。

# はじめに
私は普段から情報管理ツールとしてNotionを愛用しており、特に「[Save to Notion](https://chromewebstore.google.com/detail/save-to-notion/ldmmifpegigmeammaeckplhnjbbpccmm?hl=ja)」を使ってWebページのブックマークを整理しています。この機能が便利だなと感じたため、「同じことを業務で使用しているGoogleスプレッドシートでも実現できないか？」と考えたのが、今回の開発のきっかけでした。

# 実際の動き
![ezgif-1-21bfd7160f.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/339435/35c1f9de-2417-e1a1-fbe8-f4a69017db99.gif)

# セットアップ手順

## 1. スプレッドシートの準備

1. Googleドライブで新しいスプレッドシートを作成
2. 1行目に以下のヘッダーを入力:
   - A1: タイトル
   - B1: URL
   - C1: タグ
   - D1: 備考

## 2. 拡張機能のインストール

1. 以下のリポジトリをクローンまたはダウンロード
    https://github.com/tequila0725/web-memo-database-on-spreadsheet

2. Chrome拡張機能の設定ページ（`chrome://extensions/`）を開く
3. 「デベロッパーモード」を有効にする
4. 「パッケージ化されていない拡張機能を読み込む」をクリックし、クローンしたディレクトリを選択

## 3. Google Cloud Platform (GCP) の設定

1. [Google Cloud Console](https://cloud.google.com/?hl=ja)で新しいプロジェクトを作成:
   - ヘッダーメニューの「コンソール」をクリック
   - 「プロジェクトを選択」→「新しいプロジェクト」
   - プロジェクト名は任意、組織は「組織なし」を選択

2. 必要なAPIと認証情報の設定:
   - APIとサービスから「Google Sheets API」を有効化
   - 認証情報でAPIキーとOAuthクライアントIDを作成

3. OAuth同意画面の設定:
   - User Type: 外部
   - アプリ名: 任意
   - ユーザーサポートメール: 任意
   - デベロッパーの連絡先情報: 任意
   - テストユーザー: 拡張機能を使用するGoogleアカウント

4. OAuthクライアントIDの作成:
   - アプリケーションの種類: Chrome拡張機能
   - 名前: 任意
   - アイテムID: Chrome拡張機能のID

## 4. 拡張機能の設定

1. `.env.sample`をコピーして`.env`を作成し、以下の情報を設定:

    ```
    API_KEY=your_api_key
    SPREADSHEET_ID=your_spreadsheet_id
    SPREADSHEET_TAB_NAME=your_sheet_name
    CLIENT_ID=your_client_id
    ```

2. `manifest.json`の`client_id`フィールドにOAuthクライアントIDを入力

# 使用方法

1. Chrome拡張機能をインストールすると、ツールバーにアイコンが追加されます
2. 保存したいWebページを開いた状態でアイコンをクリック
3. ポップアップウィンドウで情報を編集:
   - タイトル（自動取得）
   - URL（自動取得）
   - タグ（カンマ区切りで複数入力可能）
   - 備考
4. 「スプレッドシートに保存」ボタンをクリックして保存


# まとめ
今回、初めてChrome拡張機能を開発してみました。
感想としては「Chrome上で拡張機能を実行すること自体」は思っていたよりも簡単でした。
しかし、ChromeのAPIを使用する場合は、認証情報を取得しサービスワーカー(background.js)を作成しなければならないなど、込み入った知識が必要になり混乱しました。

まとめると、特に以下の点が印象的でした：
- HTML/JavaScriptの基本的な知識があれば、拡張機能の開発は思ったより敷居が低い
- Google Spreadsheet APIとの連携を通じて、実践的なAPI統合の知識を得られた
- 身近な業務効率化ツールを自作することで､ 実践的な学びになった
---

今回の経験を活かして、今後も業務効率化に役立つツールを開発していきたいと思います。
完全なソースコードはGitHubリポジトリで公開していますので、興味のある方はぜひご覧ください。

次回は[@nisei275](https://qiita.com/nisei275)さんの[RustのゲームエンジンBevyでマスタデータを扱ってみる](https://qiita.com/nisei275/items/7c54cea9ffd18ab911d5)です。

# 参考
https://qiita.com/plumfield56/items/6fe255180739ba4b1a25

https://qiita.com/akky-tys/items/0fbafc4b5b48c4dd170a
Syslogを収集し、Fluentdを利用して別システムへ転送する

# 概要
Syslogを収集する環境を作成し、そのログをさらに別システムへ転送するための手順を記載します。

# 環境
本手順で取り扱う内容は、次の環境にて確認しています。
* Syslog client
マシン：Amazon EC2  
OS：Ubuntu 24.04

* Syslog server ＆ Fluentd server  
マシン：Amazon EC2  
OS：Ubuntu 24.04
Fluentd：1.16.6

構成図は次のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510470/d90eab29-3270-c5b1-23d5-a3aa79059f18.png)

Syslog ClientはSyslog serverにログを転送します。
そしてSyslog serverにFluentdを導入し、別システムへ転送する仕組みです。
なお、Syslog clientは通常、複数台存在するはずですが、本記事では話をシンプルにするために１台構成としています。

# 手順
## ログ収集環境セットアップ手順
ログ収集環境をセットアップするための手順を記載します。

### 通信設定
Syslog serverのセキュリティグループのインバウンドルールにて、Syslog clientからのUDP 514 Port接続を許可して下さい。  

### rsyslogdセットアップ**​（Syslog server）**

rsyslog.confを編集します。
```
$ sudo vi /etc/rsyslog.conf
```
編集内容ですが、clientからUDPでsyslogを受信するために次の2行をアンコメントして下さい。
```
module(load="imudp")
input(type="imudp" port="514")
```

また、syslogをfluentdに送信するために`/etc/rsyslog.d/30-fluentd.conf`ファイルを作成して下さい。

```
$ sudo vi /etc/rsyslog.d/30-fluentd.conf
```
ファイルの内容は次のようにして下さい。
全てのFacility・SeverityのログをFluentdに転送する設定です。
Facility・Severityについては[こちらのページ](https://www.infraexpert.com/study/syslog1.html)が参考になるかと思います。
```
*.* @localhost:5140
```

編集が完了したら、変更内容を反映させて下さい。

```
$ sudo systemctl restart rsyslog.service
```

### rsyslogdセットアップ**​（Syslog client）**

Syslog clientでは`/etc/rsyslog.d/30-syslogsv.conf`ファイルを作成して下さい。
```
$ sudo vi /etc/rsyslog.d/30-syslogsv.conf
```

ファイルの内容は次のようにして下さい。
全てのFacility・SeverityのログをSyslog serverに転送する設定です。
```
*.* @<Syslog server IP>:514
```

編集が完了したら、変更内容を反映させて下さい。
```
$ sudo systemctl restart rsyslog.service
```

以上でログ収集環境のセットアップは完了です。

## Fluentdセットアップ及び、別システムへの転送設定
### Fluentdインストール**​（Syslog server）**
[Fluentdのガイド](https://docs.fluentd.org/installation)に従ってインストールして下さい。
次のコマンドでは、Ubuntu24.04にFluentdをインストールします。
```
$ curl -fsSL https://toolbelt.treasuredata.com/sh/install-ubuntu-noble-fluent-package5-lts.sh | sh
```
### Config設定

fluentd.confを編集します。

```
$ sudo vi /etc/fluent/fluentd.conf
```

ファイルの中身を書き換えて下さい。
次のfluentd.confはサンプルになります。
```
<source>
  @type syslog
  port 5140
  bind 0.0.0.0
  tag test
  <parse>
    @type none
  </parse>
</source>

<match test.**>
  @type http
  endpoint <YOUR-ENDPOINT>
  open_timeout 2
  <format>
    @type json
  </format>
  content_type application/json
  headers {"Authorization": "Bearer <YOUR-ACCESSTOKEN>"}
  <buffer>
    chunk_limit_records 1
  </buffer>
</match>
```

編集が完了したら、変更内容を反映させて下さい。
```
$ sudo systemctl restart fluentd
```

# 動作確認

転送先システムにて、ログが受信できていることを確認して下さい。  
もしくはloggerコマンドをSyslog clientにて実行し、​手動で確認することも可能です。

```
$ logger TEST TEST TEST
```
 
もし、受信できていない場合、fluentdログ(/var/log/fluent/fluentd.log)を確認することが有効です。

# 参考
https://docs.fluentd.org/installation
https://www.infraexpert.com/study/syslog1.html
【Misskey】ログボを手軽にもらえるボタンが欲しい【ウィジェット】

## 初めに
https://qiita.com/nekomimi_360/items/2647a17648cec4468f87

これは以前投稿した便利なボタンウィジェットの改良版です

## ログインbotって知ってる？
https://misskey.m544.net/@LoginBonus

「ログボ」とメンションするとログインポイントをくれるボットがいます。
毎朝手打ちするのは大変なので、ボタン1つでメンションを飛ばすようにしたいと思います

## ボタンを準備
ウィジェットカラムを編集してボタンを配置します
![スクリーンショット 2024-12-12 094855.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679188/97e31575-3e71-d9cb-a2e5-25be86e6be54.jpeg)
![スクリーンショット 2024-12-12 095210.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679188/72e552e5-b883-39d2-0cbd-f6e5386e201f.jpeg)

## ボタンの機能を編集
![スクリーンショット 2024-12-12 095232.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679188/f95c188a-5e0f-ec53-ea0e-54b3f627e402.jpeg)
歯車マークを押して編集します

![スクリーンショット 2024-12-12 095443.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679188/6d477f0e-9ff8-4ec7-761a-c2608aec091b.jpeg)
①にボタン上に表示する文字を入力します。

```
Mk:api('notes/create', {
    text: '@LoginBonus@misskey.m544.net ログボ'
    visibility: "home"
})
```
②に上のスクリプトをコピペします
注意点としては前回のウィジェットと違って、投稿フォームが開かず直接投稿されます

## 出来上がり
![スクリーンショット 2024-12-12 095505.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3679188/c6e3bb4c-ac2d-d738-5d4d-59294c96b628.jpeg)
これでボタンを押しただけで投稿され、ログボがもらえるようになりました！

好きな文章に変えてみたりして、便利に活用してみてください。
では良きMisskeyライフを～～！！
[React] 再レンダリングの条件

# 条件
|条件|関連リンク|
|:--|:--|
|Propsの更新|[[React] Props](https://qiita.com/Jochun/items/10cac4b8109275e27851)|
|Propsの更新|[[React] State](https://qiita.com/Jochun/items/4f3362e1ed6868f03e81)|
|親コンポーネントの再レンダリング|[[React] Props](https://qiita.com/Jochun/items/10cac4b8109275e27851)|
|Contextの値の更新||

# 参考リンク
- [Reactのコンポーネントで再レンダリングが起こる瞬間3選](https://otaku-programmer.com/react/rendering/1/)
東京大学ブロックチェーン寄附講座　感想

# 東京大学ブロックチェーン寄附講座を受講した体験記

これまで私は独学でブロックチェーン技術の勉強を続けてきました。個人開発を進める中でSolidityやEthereumにはある程度触れていましたが、どうしても知識が偏ることが多く、ゼロ知識証明（ZK）の概念やその応用を理解するのに苦戦していました。また、SolanaやPolkadot/Astarといった他のブロックチェーン技術についても、具体的な仕組みや活用方法が曖昧なままでした。そんな時、この講座の募集を知り、「体系的に学べる絶好の機会だ」と思い、迷わず申し込みました。

---

## 講座の概要

この講座は、基礎から応用までブロックチェーン技術を日本語で学べる貴重な機会を提供していました。特に以下のような豊富なトピックをカバーしており、技術の全体像を捉えられる構成でした。

### **主要トピック**
- **はじめに，ブロックチェーン概要**
- **ビットコイン**
- **Ethereum 1.0**
- **Ethereum 2.0**
- **Dapps開発入門**
- **Dapps・エコノミクス設計入門**
- **Dappsの事例紹介（DeFi, DAO, NFTなど）**
- **Web3関連の法律**
- **ゼロ知識証明（ZK）の概要と実践**
- **ブロックチェーンにおけるZK事例**
- **L2技術**
- **Solana**
- **いろいろなL1ブロックチェーン**
- **インターオペラビリティ**
- **Polkadot/Astar**
- **エンタープライズ領域における利用**
- **Web3ニュース・トレンド**
- **グループワーク（はじめに・各自）**

### **試験について**
講座の前半部分では座学や演習を通してブロックチェーンの基礎と応用を学びましたが、グループワークに参加するには、後半の試験を突破する必要がありました。この試験は、講座で学んだ内容の理解度を問うもので、知識をしっかりと身につけていなければ合格は難しかったです。

---

## 私が挑戦したグループワーク

### **テーマ:** 地震保険プロジェクト  
私は試験を無事突破し、後半のグループワークに参加することができました。私たちのチームが取り組んだのは「地震保険」のプロジェクトです。

#### **プロジェクトの概要**
1. **NFT発行:** 各都道府県ごとにNFTを発行。利用者が賭け金（プレミアム）を設定。
2. **Chainlinkの活用:** 地震情報APIを使用し、震度データをスマートコントラクトに反映。
3. **保険金支払い:** 大きな震度が記録された都道府県のNFT保有者に対し、スマートコントラクトに預けたトークンを付与。

このシステムにより、地震被災者を支援する革新的な仕組みを設計しました。

#### **開発で使用した技術**
- **Solidity:** スマートコントラクトの開発  
- **Chainlink:** オフチェーンデータをブロックチェーンに連携  

---

## 受講を終えて

この講座を通じて、ブロックチェーンの基礎技術から最新トレンドまで幅広く学ぶことができました。特に、グループワークを通じて実践的なスキルを磨けたことが大きな収穫です。これまで独学で学んでいた内容を体系的に整理し、新たな知識を習得できたことで、技術への理解が格段に深まりました。Chainlinkの実装ついては発表までに間に合わせることができなかったのですが、グループワークを通じて実装面だけでなくコミュニケーションスキルも向上させることができたと思っています。

毎年このブロックチェーン寄附講座が行われると思うので、興味のある方や技術の実践を志している方には、ぜひこの講座を受講していただきたいです。日本語で学べる貴重な機会を活用し、ブロックチェーン技術の最前線に触れてみてください！

---

**東京大学ブロックチェーン寄附講座についての詳細は、公式ページをご覧ください！**

https://www.blockchain.t.u-tokyo.ac.jp/lecture
PostgreSQL Conference Japan 2024 参加レポート

こんにちは。インプリムのhmineです。

ふだんはOSSのノーコード・ローコードツール「プリザンター」に機能追加をしています。

https://www.pleasanter.org/

# PostgreSQL Conference Japan 2024に参加しました。

2024/12/6（金）にオフライン開催された「PostgreSQL Conference Japan 2024」。
インプリムはシルバースポンサー（展示あり）として参加しました。

https://www.postgresql.jp/index.php/jpug-pgcon2024

私は展示ブースのメンバーとして参加しつつ、カンファレンスを現地で聴講しました。
大変楽しい一日でした！

# 講演を聴講しました。

**■基調講演1　PostgreSQL 17とPostgreSQL開発最前線**

PostgreSQL17が2024/9/26にリリースされた。
・https://www.postgresql.org/docs/17/release-17.html

Vacuum機能の改善、論理レプリケーション機能の改善や、増分バックアップ機能の追加といったニュースを、開発者自らが解説。

**■基調講演2　AWS and the PostgreSQL community**

PostgreSQLの開発コミュニティの体制について。

・全世界における開発者（発表者調べ）：
　コア：7名／コミッター：30名／
　コントリビュータ（本体開発、周辺機能の開発、レビュー、翻訳　含む）：450名超
　セキュリティ：17名／インフラ：6名　←これはコミュニティ活動専用システムの部隊。
・他にAdvocacy（支援者）が多数。

AWSの社員の一部には、PostgreSQLの開発専任者がいる。（基調講演者のAWS社員2名もそれに該当）

コードベースの開発規模は年々増加傾向にある。コミュニティでレビュアーを育成することが今後の課題。

**■MySQL 8.0 から PostgreSQL 16 への移行と RLS 導入までの道のりと学び**

機密性の高い情報を扱うSaaSを運営している、スタートアップ企業の事例。（運用のベースはAWS）

アプリケーションは人力で設計・実装されるものであるためミスが多い　→　DBの仕組みによる情報漏洩防止策が必要だった。
MySQLからPostgreSQLに移行したのは、MySQLでは漏洩を防ぐ仕組みが脆弱と判断したためである。

移行に併せてPostgreSQLのRow Level Security機能を導入した。
事前調査に力を入れていたことや、移行計画に余裕を持たせていたことが幸いし、スムーズに移行をすることができた。

**■PostgreSQL でインデックスはどう使われるのか**

SQL文の読取りから内部の実行処理まで流れを確認。
・パーサ　→　リライタ　→　プランナ　→　エグゼキュータ

処理の流れに着目し「なぜインデックスを追加したのに、SELECT文を高速化できないのか？」よくある原因を解説。

もし「遅いクエリ」を検知した際には、プランナーの実行計画を確認し、「インデックスが使われていないのではないか？」という可能性も疑ってみる。

**■基礎から学ぶ PostgreSQL のバックアップ ―基本機能と運用設計**

バックアップの手法について、単純なものから解説。
・オフライン物理バックアップ　→　DB停止後、OS上でファイルをコピーする。
・オンライン論理バックアップ　→　pg_dumpコマンド、pg_dumpallコマンドでSQL文を取得する。
・オンライン物理バックアップ　→　PostgreSQLの主力機能。WAL（先行書き込みログ）の理解がカギ。

バックアップとは、それを利用してリストア→リカバリできることが前提であり、リストア・リカバリの方式を併せて理解することが重要である。

# 感想

PostgreSQLの機能、AWS等のクラウドサービスが提供する機能の理解…と、やることは、いくらでも、たくさんあると思いました。

ふだん開発に関わっている「[プリザンター](https://www.pleasanter.org/)」がPostgreSQLも使用できる（※）関係上、私の周りには、Windows版やLinux版のPostgreSQL、Dockerイメージ、クラウドサービスのPostgreSQLに触れる環境が整っています。

※：[GitHubで配布しているモジュール](https://github.com/Implem/Implem.Pleasanter)を利用する場合、PostgreSQL・MySQL・SQLServerの中から、使用するDBを選択します。
※：なおプリザンターのSaaS版（Pleasanter.net）ではAzure SQL Database固定です。

公式ドキュメントはじめ、様々な事例で紹介されているPostgreSQLの機能をこれからも試していきたいと思います。
Javaで学ぶアルゴリズム -バブルソート

# バブルソート

> バブルソート（英: bubble sort）は、隣り合う要素の大小を比較しながら整列させるソートアルゴリズム。
> アルゴリズムが単純で実装も容易である一方、最悪時間計算量は O(n2) と遅いため、一般にはマージソートやヒープソートなど、より最悪時間計算量の小さな（従って高速な）方法が利用される。

https://ja.wikipedia.org/wiki/%E3%83%90%E3%83%96%E3%83%AB%E3%82%BD%E3%83%BC%E3%83%88

# 実行環境

- JUnit 5
- Java 8

# テストコード

```java:StraightExchangeSortTest.java
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

public class StraightExchangeSortTest {

	@DisplayName("配列を渡すとソートされた配列が返ること")
	@Test
	void testStraightExchange() {
		int[] array = { 5, 12, 7, 0, 1, 14, 6, 9, 8, 3, 2, 11, 4, 13, 10 };
		int[] expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };

		int[] actual = StraightExchangeSort.straightExchange(array);
		assertThat(actual, is(expected));
	}

	@DisplayName("要素が1つしかない配列を渡すと要素が1つしかない配列が返ること")
	@Test
	void testStraightExchangeOneElement() {
		int[] array = { 5 };
		int[] expected = { 5 };

		int[] actual = StraightExchangeSort.straightExchange(array);
		assertThat(actual, is(expected));
	}

	@DisplayName("空の配列を渡すと空の配列が返ること")
	@Test
	void testStraightExchangeEmpty() {
		int[] array = {};
		int[] expected = {};

		int[] actual = StraightExchangeSort.straightExchange(array);
		assertThat(actual, is(expected));
	}

	@DisplayName("すでに昇順でソートされた配列を渡すとソートされた配列が返ること")
	@Test
	void testStraightExchangeAlreadySorted() {
		int[] array = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };
		int[] expected = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 };

		int[] actual = StraightExchangeSort.straightExchange(array);
		assertThat(actual, is(expected));
	}

	@DisplayName("要素が重複した配列を渡すとソートされた配列が返ること")
	@Test
	void testStraightExchangeDuplicateElement() {
		int[] array = { 5, 3, 5, 2, 1, 5, 3, 2, 5, 3, 5 };
		int[] expected = { 1, 2, 2, 3, 3, 3, 5, 5, 5, 5, 5 };

		int[] actual = StraightExchangeSort.straightExchange(array);
		assertThat(actual, is(expected));
	}
}
```

# バブルソートアルゴリズム

```java:StraightExchangeSort.java
// バブルソート（単純交換ソート）
public class StraightExchangeSort {

	/**
	 * 先頭から末尾に向かって隣接する要素を比較して整列させる
	 * @param array
	 * @return sortedArray
	 */
	static int[] straightExchange(int[] array) {
		int[] sortedArray = array.clone();
		int size = sortedArray.length;

		for (int i = 0; i < size - 1; i++) {
			for (int j = 0; j < size - 1 - i; j++) {
				if (sortedArray[j] > sortedArray[j + 1]) {
					int temp = sortedArray[j];
					sortedArray[j] = sortedArray[j + 1];
					sortedArray[j + 1] = temp;
				}
			}
		}
		return sortedArray;
	}

	/**
	 * 末尾から先頭に向かって隣接する要素を比較して整列させる
	 * @param array
	 * @return sortedArray
	 */
	static int[] straightExchangeReverse(int[] array) {
		int[] sortedArray = array.clone();
		int size = sortedArray.length;

		for (int i = 0; i < size - 1; i++) {
			for (int j = size - 1; j > i; j--) {
				if (sortedArray[j] < sortedArray[j - 1]) {
					int temp = sortedArray[j];
					sortedArray[j] = sortedArray[j - 1];
					sortedArray[j - 1] = temp;
				}
			}
		}
		return sortedArray;
	}
}
```
GeminiやGoogle AI Studioでアカウントを指定して開く方法

# はじめに

複数のGoogleアカウントを使っていると、GeminiやGoogle AI Studioを利用する際に、どのアカウントでログインしているか迷うことはありませんか？
複数アカウントでログインしていると、意図しないアカウントでアクセスしてしまったり、アカウントの切り替えが面倒っだったりします。

この記事では、特定のアカウントでGeminiやGoogle AI Studioを直接開く方法を紹介します。

# やり方

URLに `?authuser=hogehoge@gmail.com` を付与することで、指定したアカウントでGoogleサービスを開くことができます。

:::note warn
`hogehoge@gmail.com` を使用したいGoogleアカウントのメールアドレスに置き換えてください。
:::

### Geminiの場合

[https://gemini.google.com/app?authuser=hogehoge@gmail.com]()

### Google AI Studioの場合

[https://aistudio.google.com/?authuser=hogehoge@gmail.com]()

## 応用: 他のGoogleサービスでも利用可能

`authuser` パラメータは、GoogleカレンダーやGmailなど、他のGoogleサービスでも利用できます。

### 例: 特定アカウントでGmailを開く場合

[https://mail.google.com/?authuser=hogehoge@gmail.com]()
プロジェクトデータシートについて

この記事は、[適応型ソフトウェア開発 アドベントカレンダー 2024](https://qiita.com/advent-calendar/2024/adaptive-software-development) の 12日目です。

## プロジェクトデータシートとは

前回の記事で「ゲート」という透明性を与えるためのきっかけについて解説したが、その時に課題がのこっていたと思う。

https://qiita.com/h-kinocoboy/items/1923543b66af7043f1ad

### 課題

スクラムフレームワークは集中状態を構築して進めるため、進めているチームタスク自体もシングルタスクで進行する。そのため、状況を把握する際には１つの状態をチェックすることで進捗状況の評価を行える状態を作ることができた。

しかし、適応型ソフトウェア開発では、マルチタスク状態で進行するため複数のタスクに関する状況を俯瞰した上で、チームの進捗状況を評価する必要がある。

この状態確認を行い、適切にチームの進捗状態を把握する仕組みを作ることが大切である。

しかしながら、 `状態確認を行い、適切にチームの進捗状態を把握する仕組み` とはどのようなものなのだろうか。

その1つの事例がプロジェクトデータシートと呼ばれるものだ。


## プロジェクトデータシート
プロジェクトデータシート（以下PDS）とは、チームが進行しているすべてのタスクを一覧化したシートのことである。

そのシートにはそれぞれの「状態」を明記し、次に目指す状況を整理しておくことで、共通認識を作りやすい状況をつくるためのツールである。


### 記載例
PDSは以下のように一覧でまとめた。
あくまでこれの例は筆者がチームで取り組んだ時の事例である。

|タスク名|状態|現在の状態|次に目指したい状態|目指したい背景|
|-------|---|--------|---------------|------------|
|XXXについて学ぶ|学習|XXXのことをあまり知らない|XXXの提供方法を思案できる|XXXを顧客に提供したい|
|YYYについて思案する|思案|YYYのことを学び、調査した|YYYを協調して作れる|XXXを顧客に提供したい|
|ZZZについて協調する|協調|ZZZの方針が決定した|ZZZをリリースする|ZZZを顧客に提供したい|


#### タスク名
取り組んでいる仕事が何かを明確にするためのラベルを持つ。

#### 状態
タスクがどんな状態なのかを「学習」・「思案」・「協調」の３値で表現する。
ここの状態を常に最新化することが大切である。

#### 現在の状態
タスクが今具体的にどのような状態になっているのか、「学習」・「思案」・「協調」の値に対する根拠を記述しておく。

#### 次に目指したい状態
タスクが次具体的にどのような状態になっていてほしいのか、「学習」・「思案」・「協調」の値に対するありようを記述しておく。

#### 目指したい背景
タスクがどこから生まれたもので、何のカオスの縁にいたものなのかを記載しておき、迷わないようにしておく。


## まとめ
このような案件状況を１目で俯瞰できるシートを作っておくことで、ゲートに備えることが有効だった。
TiDBの学習リソース

## はじめに

TiDBを学ぶためのリソースは色々あるのですが、公式ページでも一覧になっていなかったのでまとめてみました。

## ウェビナー

PingCAP株式会社では定期的にウェビナーを開催しています。一度でもウェビナーに参加すると、次回以降のウェビナーの案内が届くと思います。最新のTiDBのアップデートや、初めての方向けのウェビナーも開催しているのでテーマを見てご参加ください。

なお英語版のウェビナーも多く開催していますが、残念ながら日本時間だと深夜になるケースがほとんどです。

https://pingcap.co.jp/event/?type=virtual

## PingCAP Education

PingCAPには教育用コンテンツを作成する部署があり、セルフラーニング用のコンテンツを数多く作成しています。

https://jpn.edu.pingcap.com/plus/external-catalog

最近TiDB CloudのアカウントでSSOできるようになりました。TiDBの基礎から学びたい人はこちらからどうぞ！

内容については以前書いたブログ記事を参照ください。

https://qiita.com/bohnen/items/e7772c3fe3a231cd10e2


## Youtube

PingCAPの公式youtubeチャネルです。ウェビナーのアーカイブや、イベント発表などのアーカイブを投稿しています。Subscribeお願いします！

https://www.youtube.com/@pingcapjapan

https://www.youtube.com/c/pingcap


## X

https://x.com/PingCAP_Japan

https://x.com/PingCAP

[X:@bohnen](https://x.com/bohnen) もフォローしていただけると嬉しいです。

## トレーニング

### コミュニティワークショップ

全国各地のコミュニティイベントでワークショップを開催しています。お気軽に依頼ください！
今年の実績では下記のイベントでTiDB（も含んだ）ワークショップを開催しました。

https://tokyo.serverlessdays.io/

https://serverless.connpass.com/event/332724/

https://serverless.connpass.com/event/305300/


### 有償ワークショップ

TiDBの背景にある考え方からハンズオンまで、みっちり行う有償ワークショップを定期的に開催しています。TiDB Cloud Dedicatedをベースにしています。

https://pingcap.co.jp/event/workshop/