OmniAICreator/Qiita-1.07M huggingface dataset:
pythonのheapqの記法を直感的に直す

# 背景
　Pythonのheapqを一度でも使ったことがある競プロerなら、その直感的でない記法をなんとかしてほしいと思ったことがあるはず。わざわざ優先度付きキュー専用のリストを作り、そのキューにpushしたりキューからpopしたいときに
 ```python
heappush(q, (優先度, 値))
 ```
 や
```python
pri, val = heappop(q)
 ```
などと書くのはあまりにも直感に反する。dequeなら
```python
q = deque()
```
と生成でき、appendやpopしたいときも、
```python
q.append(値)
```
や
```python
val = q.pop()
```
と書ける。heapqも同じように書きたいと思ったことは一度や二度ではないだろう。
# neoheapq
　そこで、こう書けるように新しいクラスを作った。名付けて`neoheapq`。
```python neoheapq.py
import heapq

class neoheapq:
  def __init__(self):
    self.q = []

  def push(self, h: float, val: object) -> None:
    heapq.heappush(self.q, (h, val))

  def pop(self) -> tuple:
    return heapq.heappop(self.q)

  def __getitem__(self, idx: int) -> tuple:
    return self.q[idx]

  def __len__(self) -> int:
    return len(self.q)

```
## 概要
内部でリストを作り、`heapq.heappush`と`heapq.heappop`を動かしている。それだけ。
## 使い方
### 生成
```python
q = neoheapq()
```
`heapify`に相当する機能は競プロにはあまり要らなさそうだったので作ってない。
### 追加
```python
q.push(優先度, 値)
```
### pop
```python
pri, val = q.pop()
```
`pop`を呼ぶと、もっとも優先度が小さいものの`(優先度, 値)`のタプルがpopされる。
### 最初のものを取得
```python
pri, val = q[0]
```
`q[0]`で、`q`のうちもっとも優先度が小さいもののタプル`(優先度, 値)`が返される。heapqと同じく`q[1]`以降は優先度順になっておらず、あまり意味がないので注意。
### 値の数
```python
len(q)
```
# 最後に
　これを使ってダイクストラ法のサンプルコードを作ろうと思ったんですが、面倒なので誰かやってください (丸投げ)
レガシーコードを無くすには

# はじめに

https://qiita.com/advent-calendar/2024/works-hi-2

こちらのアドベントカレンダー用の記事です。
レガシーコードを無くしていくにはどうすれば良いか、基本的な部分を書いていきます。
※ 「レガシーコード改善ガイド」とかを読まれている方には物足りない内容になるかと思います。

# レガシーコードとは？

テストがないコードだったり、複雑だったり、古い技術を使ってたり。
さまざまな定義がありますが、ざっくりと「イけてないコード」みたいなニュアンスで使われることが多いように思います。

# レガシーコードを無くせるのか？

結論から言えば、「無くすことはできない」と言えます。
レガシーコードについて書かれた本で「できる」と書かれているものはないはずです。
なぜなら、レガシー化はコードを書いた瞬間から始まっており、たとえその時美しく完璧なコードであっても、いずれは古くなり、レガシーと呼ばれてしまうからです。

では、どうすれば良いかというと、「継続的に修正し続けられる環境を整備すること」です。
本記事では、レガシーコードをテーマにしていますが、レガシーシステムや開発手法など、技術的負債全般に共通して言える部分です。

# 具体的にはどうすれば良いか

では、具体的にどうすれば良いのか？
いくつか代表的なアプローチを紹介します。

## テストの整備

最も基本的で、重要な部分です。
自動テストをしっかり整備することで、安心してリファクタリングや機能追加ができる環境を作ります。
テストがない状態では、コードを変更するたびに動作が壊れるリスクが生じます。
CIで自動実行できる仕組みを作っておくことも重要です。

## 適切なモジュール化

アーキテクチャでのアプローチモジュール化、プロジェクトの分割を適切に行うことで、部品単位でのリプレースがしやすくなります。
設計時に意識しておくことが必要ですね。

## 継続的に改善できる文化の定着

たとえば、スクラムで開発しているのであれば、「Sprintで実施するタスクの 20% は改善作業に費やす」などのルールを作って、継続的に改善ができる環境をつくります。
（裁量がない場合、ここが最も難しい部分ではあります。技術的負債が与える影響などを持ち出して責任者を説得していきましょう...）

# 番外編：マイクロサービスアーキテクチャ

マイクロサービスアーキテクチャの考え方も、レガシー化が避けられない現実を前提としています。

例えば、あるサービスが古くなったとしても、その部分だけを置き換えることでシステム全体のレガシー化を避けることができます。そのために、サービス単位を小さくしておくことがポイントとなります。（「4日でつくり直せるくらいのサイズ」というのが１つの目安）

# さいごに

レガシーコードを完全に無くすことはできませんが、残し続けてしまうと、開発のパフォーマンスやサービスに与える影響は計り知れません。
いきなり色々やるのは難しいとしても、まずは、テストコードを書くところから始めていきましょう。
Slackのリマインダーの代わりにPowerAutomateを使ってみるメリット


Slack を使っている方は、リマインダー機能も使っている方は多いと思います。
自分へのリマインドも便利ですが、チャンネルリマインダーは、チャンネルを見ているメンバーに通知が飛ばせるので有用です。

ただ、リマインドをコントロールする部分ではうまくいかないこともあります。
個人的に困っているのは、

-   権限まわりの問題（一般ユーザーでは対処できない部分）
    -   リマインダーを設定したという通知を削除できない
    -   Slackbot のリマインダーを適度なタイミングで消したいが削除できない
-   定期リマインドを一次的に中断したりができない
    -   その都度リマインダーを削除して、再作成していたりしていた

といったところでした。

リマインダーの通知でチャンネルが汚染されるのは結構不毛に感じていたので、Microsoft Power Automate で投稿することにしました。

設定も結構簡単です。
定期実行のフローを作り Slack の該当チャンネルに投稿するだけです。

![Power Automate](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553291/c5c7f908-ea26-58b4-6f8b-915cb65e4305.png)

変数を作っているのは、メッセージを時々変えるためです。

![平日の16:27に起動するように](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553291/cde4d1af-f9b8-c2e3-2c06-41bfe02ef5dc.png)

定期実行も、曜日や時間も柔軟に設定できます。
16:27 に実行、なんてのもできますし、Slack のリマインダーだと即座に設定は反映されません（体感だと 15 分くらいの余裕が必要です）が、
Power Automate の編集は結構機敏に変更されてくれます。

![ユーザーとして投稿](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1553291/e72b25a1-f7d2-e053-f7cf-ccab6600248a.png)

「ユーザーとして投稿する」にして、自分のアカウント発信でリマインドを投稿することにすると、
あとで削除することも出来ます。
（私は、手動で削除するのは面倒になったので[make](https://www.make.com/en)で夜に消すようにしてます）

ただ、自分でリマインドを投稿しているので、 **自分自身がリマインドを通知されない** という悩ましさもありますが、
そこは **気合でカバー** することにしています。

Microsoft Power Automate を使ってのリマインドにすることで、
定期リマインドを一次的に中断するといったことも、Power Automate をオフにすることで簡単にできます。
メッセージも自由に編集できますし、いろいろ便利になりました。

自分でコントロールできることが増えるとストレスも減りますね。
是非試してみていただければと思います。
Linuxに改めて感動した話

こんにちは、インフラエンジニアです。

現場の先輩エンジニアから、「OSは"i-node"という機能でファイルを管理しているよ」という話を聞きました。
i-nodeについて調べてみたのをきっかけに、改めてLinuxの構造に感動したので備忘録として書き残しておこうと思います。

### i-nodeとは

i-nodeとは、UNIX系やLinuxなどのOSがファイルの実体を管理するためのファイルディスクリプタです。
https://e-words.jp/w/inode.html

記憶装置上のどこの住所にファイルが存在するのか、OSが認識するための電話帳のようなものです。
i-node番号という一意の識別子に個々のファイルを紐づけてファイル管理が行われています。
Linuxでは"ls"コマンドに"i"オプションを付けるとi-node番号を確認することができます。

i-nodeの実体としては構造体らしいのたぶんこんな感じ?
C言語の練習中なので調べて書いてみる。

```c
typedef struct
{
    mode_t i_mode;            // ファイルタイプとアクセス権
    uid_t i_uid;              // 所有者のユーザーID
    gid_t i_gid;              // 所有者のグループID
    off_t i_size;             // ファイルのサイズ（バイト単位）
    time_t i_mtime;           // 最終修正時間
    unsigned int i_block[15]; // ファイルデータへのポインタ
    // etc...

} inode;

```



### 何に感動したのか

ここまでなら、「OSは"i-node"っていう電話帳でファイル管理をしているよ」っていうだけの話ですが、調べているうちに以下のサイトに辿り着きました。
書いてある内容としては、UNIX系OSやLinuxは全てのインターフェイスがファイルとして抽象化されているということ。
※もはやi-nodeの機能に限った範囲の話ではない笑。興味のある方はぜひ読んでみてください。


・Linuxの標準入出力の流れをまとめたサイト
https://zenn.dev/ganariya/articles/linux-file-system

・↑のサイトのリンクから見つけたUnixをまとめたサイト
https://uc2.h2np.net/index.php?title=%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%82%B9%E3%83%9A%E3%82%B7%E3%83%A3%E3%83%AB%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB



何がすごいって、

"ハードディスクはじめNIC、CDやDVDのドライブとか、なんならターミナルまで含めて全てのI/Oに関わる機能が、ファイルという形式でアクセスできるようになっている" んです!!

これに尽きます。

だめだ、書いてみると当たり前のことしか言ってないな笑
さっきまでこの12月一番の感動に震えていたのに...

#### とにもかくにも
OSのカーネルが認識できるようにするため、現実世界で実体を持つ物体が、OSの中では「ファイル」という統一された形で保管されていて、かつその現実世界にある物体が処理命令の通りに動作するよう作り込まれているって、改めてよくできているなって感動しました。


やはり普段意識することなく触れているデバイス中で動いている仕組みが少しでもわかると面白いですね。

また今回書いた内容は処理や機能が抽象化された後の話ですが、今後はそのような部分とデバイスのより物理的で電気的な動作が行われている部分の境目で、どのような処理が行われているのか、解像度を高めることができたらもっと面白そうだなと思いました。
M5PaperS3 の情報を確認してみる【M5Stack】

この記事は、「[M5Stack Advent Calendar 2024](https://qiita.com/advent-calendar/2024/m5stack)」の 15日目の記事です。

## はじめに
M5Stack社が出している、M5Paper というスマホサイズくらいの電子ペーパー搭載デバイスがあります。そのデバイスをある時から、以下の記事・ポストで書いているようにイベントで活用しています。

●イベントで大活躍する電子ペーパー名札を作る！（M5Paper と UIFlow などで作成する手順） - Qiita
 https://qiita.com/youtoy/items/545cb81fd3188e63f8aa

https://x.com/youtoy/status/1865249360243757492

https://x.com/youtoy/status/1837308975387398500

### 新型の M5Paper
そのような中、M5Paper の新型となる「M5PaperS3」が発売されました。

●M5PaperS3 ESP32-S3搭載 電子ペーパー開発キット — スイッチサイエンス
https://www.switch-science.com/products/10112

発売開始の情報をみかけた瞬間、時間休取得中の休憩中のタイミングだったため、スマホで即ポチりました。

https://x.com/youtoy/status/1867499304807805090

しかし、詳細スペックを見ずにポチっていたので、あらためて見てみようというのがこの記事の本題です。

#### 公式からの事前ポスト
公式からの事前のポスト（開発中の時も含め）を見かけていて気になっていたのですが、その中で以下のポストで標準で名札に活用できる形状になっているのを知り、より欲しくなりました。
（界隈の方から「そもそも新型のデバイスは、ほぼポチってませんでしたっけ？」と言われそうな気もする記載...）

https://x.com/M5Stack/status/1867170154586710044

## スペックを確認していく
それでは、購入元となるスイッチサイエンスさんのサイトから情報をたどっていきます。

### 名札用途で気になるスペック
情報の中で、名札の用途に直結する部分を見てみます。

「解像度540×960ピクセルの 4.7インチの E-Inkスクリーン」いう説明文や以下の画像のとおり、解像度は M5Paper と同じのようです。サイズ感も変わらずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/e721177e-ebf8-dea6-364d-9c995b5a4f5f.png)

（上で掲載していた公式のポストの写真や）以下の画像から分かるとおり、名札として使う際に便利そうな部分が増えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/31b0c395-f53f-2430-c8cd-b0c038bae0a4.png)

### それ以外
その他の部分を見ると、ポートは減っていたり、バッテリーの容量は増えていたりするようです。

センサーなどでは、温湿度センサーがなくなり、ブザー・IMU は増えていてというように見えます。

ざっくり見たところで、自分が気になったところは上記のとおりです。

### 公式のページも見てみる
さらに、スイッチサイエンスさんのサイトの下部に記載の、公式サイトも見てみます。

●m5-docs
 https://docs.m5stack.com/en/core/PaperS3

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/86f95e38-aa21-d95d-a0fe-847869e50ea8.png)

とりあえず、以下のダウンロードモードの部分は気になったところです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/6bdd0e34-d1ba-7858-4f89-1d176fd97d7c.png)

開発絡みの情報では、公式に記載があるのは今のところ以下のようです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/50868/b9b003aa-0e8e-5da0-8f11-a28554e67406.png)

M5Unified へのリンクと、Platform.IO関連の記載がある形です。

●m5stack/M5Unified: Unified library for M5Stack series
 https://github.com/m5stack/M5Unified

個人的には UIFlow の対応がどうなるか気になったところですが、M5Burner を見てみても 記事執筆時点では M5PaperS3用のファームウェアは出ていなそうでした。

## 【2024/12/21 追記】
M5Burner で M5PaperS3用のファームウェアが配信されるようになったようです（UIFlow 2.0用）。

https://x.com/youtoy/status/1870335481604624690
C#にドキュメントコメントを入れよう

## コメントを入れよう

プログラムの中のコメントは、やはり必要です。
コードの可読性を向上させ、チーム開発を円滑に進め、長期的にはコードの保守性を高めます。

すでにご存知のことと思いますが、C#はXMLドキュメントコメントを設定することができます。関数やクラスのコメントを所定のルールで作成すると、IDEのサポートを受けることができます。
具体的には、Visual StudioやRiderなどのIDEで, コード補完時にツールチップとしてコメント内容が表示されます。関数の定義元に戻り、コードを読み返す必要がなくなります。

知らなかった方は、これを機会に利用を検討されてください。

## C#の場合
サンプルのクラスを例に、動作を確認してみましょう。

以下は、本のタイトルと著者名をプロパティに持つBookクラスです。
summaryやreturnsのタグで囲まれている箇所が、コメントです。

```csharp:Program.cs
/// <summary>
/// 本の情報を管理するクラスです。
/// </summary>
public class Book
{
    /// <summary>
    /// 本のタイトルを取得または設定します。
    /// </summary>
    public string Title { get; set; }

    /// <summary>
    /// 本の著者を取得または設定します。
    /// </summary>
    public string Author { get; set; }

    /// <summary>
    /// 本の情報を文字列形式で取得します。
    /// </summary>
    /// <returns>
    /// タイトルと著者を含む文字列。
    /// </returns>
    public string GetBookInfo()
    {
        return $"タイトル: {Title}, 著者: {Author}";
    }
};
```

このクラスのインスタンスを、コンソールに出力するのが以下のコードです。
GetBookInfoで文字列として値が返ってきます。
```csharp:Class.cs  
var book = new Book
{
    Title = "吾輩は猫である",
    Author = "夏目漱石"
};

Console.WriteLine(book.GetBookInfo());

```

GetBookInfo()にマウスカーソルをかざすと, 直前に作成したコメントの内容がホバー表示されます。現在のカーソルの位置で、関数の仕様を把握することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/123580/0c861345-b8a4-8bbe-a109-1fb6c6f1f079.png)

## まとめ

C#のドキュメントコメントのルールに従うことで、IDEのサポートを最大限受けることができます。過去のコードを振り返るのではなく、コードを書くという建設的な作業に集中できるというわけです。

XMLのタグは他にもあるため、調べてみてください。

### 参考にした情報

https://learn.microsoft.com/ja-jp/dotnet/csharp/language-reference/xmldoc/

https://blog.jbs.co.jp/entry/2023/01/30/090000

https://ufcpp.net/study/csharp/sp_xmldoc.html
(理系フリマ(4))シンセ先輩からもらったCore 2 duoでArduino UNO3をLチカ(4)


参考


https://zenn.dev/kotopasi/articles/8aff177a46ff62



目的
Arduinoの起動からLチカまで

FUSEと言う実行環境をなぜかインストールしなければならない
Arduino IDEの公式ホームページにもかいてある?


いろいろ
コマンドをまとめて実行できないようにしているのは、
何も考えずにコピペでまとめて実行しようとする
おばかさんがいるために1行づつしか実行できないように
強制
(こんだらといったらロードローラー、強制ギブスといったらほしひゅうま)





結果

```

user1@user1-Vostro-220s-Series:~$ ./arduino-ide_2.3.4_Linux_64bit.AppImage
[16229:1215/112157.334537:FATAL:setuid_sandbox_host.cc(158)] The SUID sandbox helper binary was found, but is not configured correctly. Rather than run without sandboxing I'm aborting now. You need to make sure that /tmp/.mount_arduin2vpEhn/chrome-sandbox is owned by root and has mode 4755.
Trace/breakpoint trap (コアダンプ)


```

-気になるかたは、次へ-
-------------------------------


https://qiita.com/caa45040/items/55635477687bf3294aa9


-------------------------------




手順


●FUSEのインストール

```

sudo add-apt-repository universe

```

```

sudo apt install libfuse2

```

●いろいろ


```

sudo usermod -a -G dialout $USER

```

↓失敗するが気にするな

```

sudo chmod a+rw /dev/ttyACM0

```

```

cd

```

```

cd Downloads

```

```

mv arduino-ide_2.3.4_Linux_64bit.AppImage ..

```

```

cd ..

```

```

mkdir arduino

```

```

mv arduino-ide_2.3.4_Linux_64bit.AppImage arduino

```

```

cd arduino

```


```

chmod a+x arduino-ide_2.3.4_Linux_64bit.AppImage

```

●Arduino IDEの実行


```

./arduino-ide_2.3.4_Linux_64bit.AppImage

```
【Unity】Editor.CreateCachedEditorを使ってInspectorで使えるEditor拡張を作った。

## 完成系
### Transform
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/0bbd0960-fa99-2c32-d7c6-b5f9ea161c60.png)
### ScriptableObject + ScriptableObject内のTransform
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/94865bbd-3d32-0016-bff9-6c27f38df062.png)
## 実装
実装に当たって３構成で作っています。
1. タイトルバー
2. キャッシュエディター  ← 本命
3. 区切り線

## タイトルバー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/1ef9c711-241a-da07-14e2-0908c3d60116.png)

タイトルバーの作成には以下の２つがあります。
- [EditorGUI.InspectorTitlebar](https://docs.unity3d.com/ja/current/ScriptReference/EditorGUI.InspectorTitlebar.html)
- [EditorGUILayout.InspectorTitlebar](https://docs.unity3d.com/ja/2020.2/ScriptReference/EditorGUILayout.InspectorTitlebar.html)

EditorGUILayoutの場合、表示位置の設定ができません。(変数の下に自動的に表示される仕組みになっています。)

今回はEditorGUILayout.InspectorTitlebarの内部で行われている処理にプラスして
インデントを追加したかったのでEditorGUI.InspectorTitlebarを使用しました。
```cs
Rect rect = GUILayoutUtility.GetRect(GUIContent.none, new GUIStyle("IN Title"));
// インデント
rect.x += _indentLevel; 
rect.width -= _indentLevel;

UnityEngine.Object targetObject = property.objectReferenceValue;
_isFoldoutOpen = EditorGUI.InspectorTitlebar(rect, _isFoldoutOpen, targetObject, true);
```

## キャッシュエディター
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/de007665-95b2-6f1b-ee1a-f08313e31a86.png)

今回の肝。[Editor.CreateCachedEditor](https://docs.unity3d.com/jp/2018.4/ScriptReference/Editor.CreateCachedEditor.html) を使用しています。
タイトルバーが展開されているときに表示しています。

Editor.CreateCachedEditorの引数targetObjectの型はUnityEngine.Objectなので
TransformやRigidbody、ScriptableObjectなどが入りますが、
ScriptableObjectのみを対象としてもいいかもしれません。
```cs
if (_isFoldoutOpen)
{
    EditorGUI.indentLevel++;

    // キャッシュされたエディターを作成
    Editor.CreateCachedEditor(targetObject, null, ref _editor);

    // 最後のキャッシュされたエディターのインスペクターGUIを描画
    _editor.OnInspectorGUI();

    // 変更を確認し、必要に応じてシーンを再描画
    using var changeCheck = new EditorGUI.ChangeCheckScope();
    if (changeCheck.changed)
    {
        SceneView.RepaintAll();
    }

    EditorGUI.indentLevel--;
}
```

## 区切り線
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/3739a695-e6fa-9d4a-36b6-1e70d2e8b950.png)

キャッシュエディターが表示されているとき、どこで終わっているかがわかりにくいため
区切り線を付けました。
そのため、タイトルバーが展開されているときに表示しています。
```cs
if (_isFoldoutOpen)
{
    // 区切り線を追加
    GUILayout.Space(1f);
    Rect lineRect = EditorGUILayout.GetControlRect(false, 2f);
    lineRect.x += _indentLevel;
    lineRect.width -= _indentLevel;
    EditorGUI.DrawRect(lineRect, LineColor);
}

GUILayout.Space(15f);
```

## 終わりに
基本的にはScriptableObjectで使える機会があるものではないかと思います。
今回作ったものは、簡単に実装しているため複雑なもの(主に配列)には使えません。
そして今回のEditor拡張を使用する場合、使いやすいやり方としてはカスタム属性を使用する方法が良いのではないかと思います。
自分は以下の画像のように[CachedEditor]を付ければ使えるようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3674844/fb3bb630-c153-e118-f33e-6f300e6abc4e.png)
RemoteViewsをActivity上に表示する

AppWidgetやカスタムNotificationでRemoteViewsを扱うことがあると思いますが、このRemoteViewsはAppWidgetやNotificationとしてしか使えない、訳ではありません。
直接アプリ上に表示することもできます。

テンプレートでAppWidgetを作ったものをシンプルに整理すると以下のようになります

```kotlin
class MyAppWidget : AppWidgetProvider() {
    override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
        for (appWidgetId in appWidgetIds) {
            val views = RemoteViews(context.packageName, R.layout.my_app_widget)
            appWidgetManager.updateAppWidget(appWidgetId, views)
        }
    }
}
```

ウィジェットとして表示すると以下のようになります。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/1b5ee457-9f64-f93f-3c3d-03ee6f9116e3.png)

RemoteViewsはこれですね

```kotlin
val views = RemoteViews(context.packageName, R.layout.my_app_widget)
```

これをActivity上に表示してみましょう。
とりあえずコンテナとしてFrameLayoutを配置し、そこに表示差せます。

```activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity"
    >

    <FrameLayout
        android:id="@+id/container"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"
        />
</androidx.constraintlayout.widget.ConstraintLayout>
```

RemoteViewsとはどういうものか？というのを端的に言えば、他のアプリにViewを表示してもらうための、ParcelableなViewの構築情報と言えます。ホームアプリやシステムUIはRemoteViewsを受け取り、Viewを構築して表示しているわけです。つまり、RemoteViewsの情報を使ってViewを作ることができます。

それはRemoteViewsが持つ、`apply`メソッドです。
以下のように使います。

```kotlin
val views = RemoteViews(packageName, R.layout.my_app_widget)
val view = views.apply(applicationContext, binding.container)
binding.container.addView(view)
```

これで以下のようにActivity上にRemoteViewsを表示することができます。

![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/155171/1a126014-2b69-5dea-f2de-e944bd8cb145.png)

`apply`メソッドの第一引数のcontextは通常applicationContextを指定します。
これによって、RemoteViewsのレイアウトからViewがInflateされ、RemoteViewsに渡した各種設定を反映したViewが返却されます。

---

ウィジェットのプレビュー機能が必要な場合に、同様のレイアウトのViewを別に作ったりする必要は無く、RemoteViews作成ロジックをそのまま使ってプレビュー表示をさせる、といった用途で活躍しそうです。
ホームアプリのウィジェットのようにプロセス間通信で他のアプリからRemoteViewsを受け取って表示する機能を作ることもできますね。

以上です。
Windows 11 で Google 日本語入力を設定する

# はじめに
今回はWindows 11で標準利用可能なMicrosoft IMEをGoogle日本語入力に切り替える手順を記載します。

# 今回の実行環境
OS：Wiindows 11
CPU：Intel Core i5-8265U
メモリ：8GB

# Google 日本語入力の要件
- Windows
OS: Windows 10 以降（Windows 7 以前のサポートは終了しております。）
CPU: 64bit x86 CPU
メモリ: お使いの OS が推奨する環境以上
ディスク容量: 400 MB 以上のディスク容量

Linux, Mac, Androidの場合は [こちら](https://support.google.com/ime/japanese/answer/166752?hl=ja#zippy=) を参照ください。

# インストール前
標準設定のMicrosofr IMEが設定されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/7a9d9a0c-8e76-c7df-f9c5-9900e7389278.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/b62577bd-ed17-2fdc-a0af-5ce4a013b295.png)


# インストール
以下のURLにアクセスし、「WINDOWS 版をダウンロード」をクリック
[https://www.google.co.jp/ime/](https://www.google.co.jp/ime/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/9b284cf9-caea-49d9-2889-1a64ab6e727e.png)

利用規約を読み、「同意してインストール」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/9ef8ddc9-917d-7964-ddf5-6a34a947499c.png)

適宜、ダウンロード先を指定してインストーラーをダウンロード
今回は、ローカルのダウンロードフォルダ配下にダウンロードしました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/3663cea8-e1d1-6644-82cb-4279eafec961.png)

ダウンロードしたインストーラーを実行
「ユーザーアカウント制御」のメッセージが出た場合、メッセージに従ってください。

実行するとインストールが進行し、完了後「Google 日本語入力」の初期設定画面が表示される
今回はデフォルトのまま、「OK」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/7980eaf9-1fd4-2ec4-0197-b51bd56bab4f.png)

インストール完了後からIMEがGoogle　日本語入力に切り替わっている。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/50c1ac63-0e20-269e-07ea-f265a2b2b962.png)

「設定」>「地域と言語」>「言語と地域」内の「言語」配下の「日本語」右側の三点リーダーをクリックし、「言語のオプション」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/4df06947-fe9c-1101-7e91-81d928fe8292.png)

「キーボード」が配下に「Google 日本語入力」が追加されている
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/423748ac-2b42-1728-aaf0-a1ef2c393957.png)


＃ おまけ
Google 日本語入力をアンインストールしたい場合は、以下のいずれかを実施する
- 「設定」>「地域と言語」>「言語と地域」>「オプション」内の配下に「Google 日本語入力」右側の三点リーダーをクリックし、「削除」をクリックして再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/fe1d584c-b5a7-5443-3071-d7fec1fc162e.png)

- コントロールパネルからアンインストールして、再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3616519/58d2c560-5abd-bf7f-4547-20712b7c310c.png)

# さいごに
今回はWindows 11のIMEにGoogle 日本語入力を設定してみました。
例によってChatGPTを学習に使ってみた

記載内容は所属会社を代表したものではなく、私の個人的な意見ということをご了承ください。

# はじめに
さて、10月から「AWS Certified Machine Learning Engineer - Associate」の正式版がリリースされましたね。
前回の「AWS Certified AI Practitioner」の結果を踏まえて、どのように対策すれば良いのかを通勤の電車(往復3時間)で考えてみました。
(1度目に全く勉強せず受験したところ落ちてしまいました(^_^;)「AWS Certified AI Practitioner」と同日受験)

# 前回のおさらい
「AWS Certified AI Practitioner」の受験の際、ChatGPTを学習に使う方法を考えて実践してみました。
今回も同じくChatGPTを学習に使っていこうと思います。

https://qiita.com/wasyokusatoshi/items/10b3e00594eb7edb6d95

# 今回する事
・より、高度な問題への挑戦
・新形式の問題への対応

# 実施策
ここでスキルビルダーの公式問題演習を使います。
<a href="https://explore.skillbuilder.aws/learn/course/19689/exam-prep-official-practice-question-set-aws-certified-machine-learning-engineer-associate-mla-c01-japanese">Question Set: AWS Certified Machine Learning Engineer - Associate (MLA-C01 -Japanese)</a>
![1000008422.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780811/6585b408-b98d-c24d-b45b-88521f9633d0.jpeg)
かなり本番に近いレベルを出題してくれるようになったのではないでしょうか？

準備は出来ました！
テスト本番までにこれで問題をたくさん作ってもらいましょう！

# ポイント
今回はテスト範囲と公式問題の出題例だけを与えて問題を作ってもらってます。
故にハルシネーションの抑止対策は一切しておりません。
それらしい問題は作ってくれるので、矛盾が無いかを自分で調べることをお勧めします。
と言うより、これにより的を得た勉強になると思います。(まぁBedrockを使えって話でもあるが、スマホからでは無理がありました。)

# 結果発表！
![1000008424.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780811/2134c95f-8143-3ad0-81c2-d89fde034894.jpeg)
まぁあくまでもAIは補助です。これを使う人間側がAIに言われたことを全部真に受けるのではなく、AIからもらった回答を見て、自分の疑念を払拭できてれば効率のよい勉強となると思いますし、その答え合わせの場が試験の場になると思います。

# 感想
今回使用したのは、無償版のChatGPTでGPT4に基づいて、2023年10月までの情報を学習してるらしいです。
まぁBedrock以外はそれなりに的を得た回答をしてそうなので、そこそこ使えそうな感覚です。
どうにか「2025 Japan AWS All Certifications Engineers」の資格をもらうことができました！
それでは！
子育てとITエンジニア

![OIG1.mDR_9kUYdBKL2uKqQ.Hc.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12035/b5a35b83-f1b1-ff47-24dd-2891635b049b.jpeg)


Qiitaのアドベントカレンダーに参加したいと思いつつ早何年、女性エンジニア向けのアドベントカレンダーがあると知り、今回初めて参加表明させていただきました。ちょっと何を書こうかワクワクしています。

エンジニアになって40年、還暦も過ぎましたが、まだまだ現役でエンジニアをしています。
若宮正子さんのように、80代になってもプログラマをしていたいと思っています。
さて、長い間にはいろいろありました。

## なぜエンジニア(プログラマ)になろうとしたか
当時はまだプログラマがとても珍しい職業でしたが、「将来性あり」と「在宅でも仕事ができる」という謳い文句をどこかで聞き齧り、「これだっ」とばかりに飛びついたのでございます。

しかしながら地方在住、親からは「家を出るな」と言われていたので、地元の製造業の情報処理部門がスタートでした。
それでもUnixやperl、informixなどを使えていたのはラッキーだったのかもしれません。

## 子育てとプログラマ
やがて結婚し、子供が産まれると同時に仕事と子育ての両立が難しくなり、泣く泣く退職。
それでも合間を見てはHTML+CSSなどをいじったりしていました。
ちなみにこの時に生まれた長男は現在、やはりエンジニアをしています。

子育て期間中は状況に合わせてパートや派遣など、働き方を変えつつもずっと職種はITエンジニアでした。
VBやVB.netで製造業向けのWindowsアプリケーションをひたすら作っていました。
もちろん、子育てしながら仕事と勉強で大変でしたが、それ以上に楽しい! 
現場の方の「便利になった」の一言がとても嬉しく、やりがいを感じていました。

## フリーランスエンジニア
子育てが一旦落ち着いた頃、なんと今度は双子妊娠がわかり、派遣で続けてきた仕事を退職。
今度こそ復帰できなそう...と思ったのですが、双子が1歳になる頃、派遣先の上司から「フリーランスで仕事を請けてみないか」と夢のようなお言葉をいただきました。
この時に派遣先の上司に背中を押してもらえなかったら、今の私はなかったかもしれません。
とても感謝しています。

双子育児とフリーランスエンジニアの仕事の両立は前にも増して大変...
午前中に外遊びを目一杯させて、午後のお昼寝の時間と子供達が寝静まってからが勝負です。

それから18年、フリーランスエンジニアとして、派遣でお世話になった会社だけでなく、いろいろな会社の開発の仕事を請けさせていただきました。
その間にPHPやLaravel、Pythonなどを教材や書籍で学びつつWeb系にシフトし、現在はまた会社員としてエンジニアをやっています。フルリモートで働けていることに感謝しかありません。

## 最後に
今までを振り返ってみると、エンジニアの仕事をずっと続けてこれたのはこれかなぁと思うものを挙げてみます。
- 地道にコツコツと勉強
- あきらめない(あきらめたらもったいない)
- とにかく楽しむ

子育て中の女性エンジニアの皆さん、すべての女性エンジニアの皆さんに大きなエールを贈ります。
[2024年版]Moddable版ｽﾀｯｸﾁｬﾝ振り返り

私が現在コントリビュートしている[Moddable版のｽﾀｯｸﾁｬﾝ](https://github.com/stack-chan/stack-chan)について、この1年は大きく変化があったので紹介も兼ねて振り返っていこうと思います。

PR([#234](https://github.com/stack-chan/stack-chan/pull/234) ~ [#306](https://github.com/stack-chan/stack-chan/pull/306))から主に機能と開発環境に分けてピックアップしていきます。

[](https://github.com/stack-chan/stack-chan/pull/235)


## 機能

- [Integrate AI Stack-chan Web API #235](https://github.com/stack-chan/stack-chan/pull/235)
    - スマホからｽﾀｯｸﾁｬﾝを操作するアプリ[ｽﾀｯｸﾁｬﾝ CONNECT](https://notes.yh1224.com/stackchan-connect/)対応
    -  APIを通じて「会話」「台詞」「表情」機能が動作する総合的なｽﾀｯｸﾁｬﾝアプリとしては初めてかも
    -  簡易的なWebAPIを実装する仕組みも実装
- [add more decorators #240](https://github.com/stack-chan/stack-chan/pull/240)
    -  上記の「表情」機能に合わせて実装
    -  CanvasのPathを駆使したアイコン表現(このあたりからChatGPTの恩恵が出てくる
- AI機能にClaude3 [#241](https://github.com/stack-chan/stack-chan/pull/241), Gemini対応 [#254](https://github.com/stack-chan/stack-chan/pull/254)
    - ChatGPT以外のAIサービスもcurlのサンプルがあれば大体はすぐに対応できるようになった
    - そろそろ共通化やstream対応をしていきたい
- [トーンを鳴らす](https://github.com/stack-chan/stack-chan/pull/291)
    - ビープ音など操作音を追加できるようになりました
    - これに合わせてTTS全般もリファクタリングを実施し、各TTSごとの実装差異も少なくなったかと思います
- [AIｽﾀｯｸﾁｬﾝ機能](https://github.com/stack-chan/stack-chan/pull/302)
    - 今まで音声入力に対応してなかったため単独での音声会話機能ができなったが、ようやくの実現
    - 主に`multipart/form-data`の実装と音声バッファのメモリ管理に苦労した


## 開発環境

- [PCシミュレータ対応 ](https://github.com/stack-chan/stack-chan/pull/251)
    - Moddableの強みでもあるPCシミュレータ上での開発に対応
    - プラットフォーム次第ではあるが、今では音声出力や入力にも対応
- modのドキュメント更新
    - 一部未完了のものはありますが、動作方法が不明との意見が多かったためドキュメントを追加した
    - ファームウェア側もそろそろ更新していきたい
- [[CI]actions/setup cache moddable and esp32](https://github.com/stack-chan/stack-chan/pull/277)
    - GitHubActionsによるプッシュ時のビルドに時間がかかっており、結果の確認に時間がかかっていたものが大幅に短縮されるようになった
    - これをきっかけにCI周りの改善を入れたりと、ちょうどGitHub Actionsを勉強する良い機会になった
- [ESLintとPrettierからBiomeへ移行する](https://github.com/stack-chan/stack-chan/pull/287)
    - ESLint8系のdeprecatedを契機に単一で実現できるBiomeへ移行
    - 動作自体も早く、単一のツールとなったことでメンテもしやすくなった
- Code Rabbit対応
    - AIレビューにより、主に実装の書き方的な指摘についてはあまり考える必要がなくなり、レビューとしての負荷も下がったかと思う。ただ真面目に対応していくのはとても大変


## 振り返って

機能面では大幅にできることは増えてはないものの、待望のAIｽﾀｯｸﾁｬﾝ化対応できたりと１つのアプリケーションとして提供できる幅は広がったかと思います。

また、開発環境面も通常のWeb開発に近い体験を目指してましたが、ローカルでの開発環境〜CIまで大きく体験が改善されたかと思います。

来年にはもっとユーザがmodの開発をしていけるようにドキュメントや設定値管理などの仕組みを改善していけたらなーと思っています。
ChatGPTをどう使う？『ノー勉』『教科書持込』『予習バッチリ』で理解する3手法

## はじめに
　ChatGPTのような大規模言語モデル LLM を専門的なドメインのタスクに適用する際には、主に通常利用、RAG、ファインチューニングの3つの方法があります。これらは、モデルを「専門性の高いテストを受ける、一般的なことを幅広く知ってる優秀な学生」になぞらえると理解しやすくなります。

## 内容
### 1.通常利用
![1000002375.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631481/fa991b97-f70c-e6f4-bccf-b240b0cd7ec7.jpeg)

→ 「頭のいい学生がノー勉で専門的なテストを受けるイメージ」

　モデルは幅広い知識を持っているものの、専門的なドメインに特化した事前準備はありません。訓練済みの一般知識に頼り、その場で最善の回答を出します。

### 2.RAG
![1000002376.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631481/162def27-e26a-e2bf-40a5-a5d4255f12f8.jpeg)

→ 「頭のいい学生が教科書持ち込み可だけどノー勉で専門的なテストを受けるイメージ」

　モデルは自前の知識だけでなく、外部の情報源（教科書）をその都度参照できます。これにより曖昧な部分も正確に補完し、信頼度の高い回答を導くことが可能になります。

### 3.ファインチューニング
![1000002377.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631481/d6d4023d-b14e-1837-f07d-5adc52ea34fb.jpeg)

→ 「頭のいい学生がテスト前に教科書をしっかり読んで勉強をしてから専門的なテストを受けるイメージ」

　モデルを専門的なドメイン合わせて追加学習し、その分野に特化した知識を獲得させます。その結果、より的確で専門的な回答が可能となります。

## まとめ
　これらの比喩で、3つの手法の特徴が明確になります。

- **通常利用**：頭のいい学生がノー勉で専門的なテストを受けるイメージ

- **RAG**：頭のいい学生が教科書持ち込み可だけどノー勉で専門的なテストを受けるイメージ

- **ファインチューニング**：頭のいい学生がテスト前に教科書をしっかり読んで勉強をしてから専門的なテストを受けるイメージ
[KDE Plasma] Firefox のピクチャーインピクチャーのバグの対処方法

# はじめに

今となってはEdgeやGoogle Chromeをはじめ，代表的なブラウザにはピクチャーインピクチャーがプラグイン無しで標準搭載されている．Firefoxも例にもれず，この機能を有している．

しかし，Windowsや（たぶんMacOCも）正常に動作するが，Linux（私の環境は後述）上ではこれが正しく機能しないのである．それに対する対処方法がまとめられている日本語記事がなかったので，ここに共有する．KDE Plasmaをよく使いこなしている人にとっては当たり前のことであるが．

# 対処方法

## 著者の環境

- Linuxディストロ：Arch Linux
- デスクトップ環境（DE）：KDE Plasma 6
- ブラウザ：Firefox

## 対処方法

根本的なバグはDE，もしくはArch Linux，Firefoxのコントリビューターに任せるとして，現時点でのピクチャーインピクチャーを動作させるための設定を以下に述べる．

1. ピクチャーインピクチャーを起動する
1. ピクチャーインピクチャーで開かれた動画を右クリックし，「More actions」->「Configure Special Window Settings」をクリック
1. Window Rulesという名前の新しいウィンドウが表示される．ここで，以下のように設定する：
1. 「Match whole window class」をYes
1. 「+Add property」から「Keep above other windows」の右にある「+」ボタンを押し，新たにルールが追加されていることを確認
1. 設定を「Yes」にする
1. 再起動する
1. ピクチャーインピクチャーをテストする
15日目: BinaryTreeを実装する

[競プロ用ライブラリを作る Advent Calendar 2024](https://qiita.com/advent-calendar/2024/yukkku-ribitol)の15日目です.

https://qiita.com/advent-calendar/2024/yukkku-ribitol

# BinaryTreeって?

列の情報を木で管理するデータ構造です.
「途中に挿入したり途中の要素を削除するコストが低い配列」として使えます.

# 仕組み

列の情報を木で管理します.
どういうことかというと, 列$x_1,x_2,...,x_N$と列$y_1,y_2,...,y_M$をくっつけた列$x_1,...,x_N,y_1,...,y_M$を「列$x$の表現と列$y$の表現が子になってる2分木」で表現するということです.

↓の図のように再帰的にデータを表現します
```mermaid
graph TD;
    A["[a, b, c, d, e]"]
    B["[a, b, c]"]
    C["[d, e]"]
    D["[a, b]"]
    A-->B;
    A-->C;
    B-->D;
    D-->a((a));
    D-->b((b));
    B-->c((c));
    C-->d((d));
    C-->e((e));
```

この方法ですが, こういうケースみたいなのが与えられると先頭の要素を見るのに$O(N)$かかってしまい遅いです.

```mermaid
graph TD;
    A["[..., w, x, y, z]"]
    B["[..., w, x, y]"]
    C["[..., w, x]"]
    D["[..., w]"]
    A-->B;
    B-->C;
    C-->D;
    A-->z((z));
    B-->y((y));
    C-->x((x));
```

これを解決するに, 偏り過ぎないようにいい感じにバランスを取る必要があります.

バランスをとる方法は色々なのが考案されていますが, 以前[再発明](https://www.tellpro.net/yukkku/articles/JXgwUHjugIMwiQUjBoGvclCztzLuBesn)したことがあるWeight Balanced Treeというものにしてみます.

これは「片方の子の要素数がもう片方の要素数の3倍未満」を保つようにするんですけど, この基準から外れたら図のように操作すれば上手くいきます

<img src="https://upload.wikimedia.org/wikipedia/commons/c/c4/Tree_Rebalancing.gif"/>

画像: https://commons.wikimedia.org/wiki/File:Tree_Rebalancing.gif

証明は[以前やった](https://www.tellpro.net/yukkku/articles/JXgwUHjugIMwiQUjBoGvclCztzLuBesn)んですけど, かなり大変だったので省略します.

# 実装

- [`binarytree.rs`](https://github.com/Yukkku/ribitol/blob/main/src/binarytree.rs)

折角なのでunsafe Rustをゴリゴリに使ってみました. 木の各頂点は自身の要素数を持たず,「左の子の要素数」を持つようにします.
一番根本だけが全体の要素数を持って, そこから探索するときに要素数を逐一調べていく感じです.
末端の要素かそうでないかの情報を減らしてメモリ削減になります.
正直あまり意味はないですが, 折角ライブラリを整備するのでそういうところまで徹底しましょう.

# まとめ

いかがでしたか?

明日は便利そうで実際はあんまり使う機会はないものを実装します.
個人開発サービスは生き続けたければマネタイズが必要なお話し

# はじめに

集合駅検索サービスKokoneをリリースし1周年となりました！
現在、皆様のお陰様で、月間1.1万人以上のユーザー様にご利用頂けるサービスまで成長することができました🎉

![](https://storage.googleapis.com/zenn-user-upload/5e8c53226b4f-20241214.png)

Kokoneは下記の記事でご紹介させて頂いている様に、
可能な限り無料の技術スタックを使って、運営をし続けてきましたが、

大変有り難いことなのですが、遂に月間1万人を超えるあたりで、
Webサーバーのトラフィックが限界を迎え、月額費用がかかる様になってしまいました。。。😢

https://zenn.dev/kokone/articles/af675c1d2690bb

今回こちらの記事では、
いち個人開発サービスで無料運用が難しくなった事例の共有と、
月額費用をペイするためのマネタイズの検討事例の共有をさせて頂ければと思います!

https://kokone-app.com/about?utm_source=qiita&utm_medium=referral&utm_campaign=monetize-demands-top


# 個人開発WEBサービスの無料運営の限界

Kokoneでは、[Render](https://render.com/pricing)というサービスでNext.js(App router)のWEBサイトをホスティングしています。

Renderは非常に良心的なサービスでして、
下記の様なスペックのマシンであれば、24時間サーバーを立ち上げ続けられるだけの、無料枠を提供してくれています。(お世話になっています🙇🙇🙇)

* CPU: __0.1CPU__
* Memory: __512MB__
* InBound Bandwidth: __100GB__

あまり知られていない&私も知らなかったのですが、
上記の無料枠の上限内で使っていれば、永遠に無料で使っていけると夢を見ていたのですが、

実際には他にもサーバーを有料化しなければならないタイミングがあるそうで、
今回Kokoneはそのうちの一つである下記の __Service Initiated traffic threshold__ という閾値に達してしまい、急遽Webサーバーを止められてしまいました。。。

https://render.com/docs/free#service-initiated-traffic-threshold

どうやらDBや外部APIなどへのトラフィックが多い場合に、
この閾値に引っかかるとのことですが、Kokoneは特別これらが多いわけではないので、
恐らく月間1万人程度のトラッフィックがある場合には、ほとんどのサービスでこの閾値に引っかかってしまうのではないかなと予想しています。

サービス停止された場合、
復旧には$7/月のStarterプランへ移行する必要があったため、
遂にKokoneは月額ゼロ円運用ができなくなり、泣く泣く月額費を払って運営をすることになりました。

# サーバー費を稼ぐための広告マネタイズ

Kokoneではこれまで、Hotpperを用いたアフィリエイト広告によるマネタイズのみを導入していました。
このアフィリエイトの成果は"お店予約"がトリガーとなるため、
現状はほとんどのユーザーは"駅検索"をメインとしてご利用頂いているため、月に数件(数百円)程度の収益にしかなっていませんでした。

今回のサーバー有料化を機に、
WEB広告によるメディアとしてのマネタイズの検討を本格的に始めました！

## インタースティシャル広告の導入

運営しているWEBサービスをメディアとして、
広告を貼ってマネタイズする場合、メディアは基本的にGoogle Adsenseの様なSSPサービスと契約する必要があります。

![](https://storage.googleapis.com/zenn-user-upload/7d688d235af9-20241214.png)

広告には基本的に下記の様なタイプがあります。
![](https://storage.googleapis.com/zenn-user-upload/47cc2f7e4cb8-20241214.png)
(参考: https://meny-meny.com/application-ad-format/)

これらはそれぞれサイトの特性や収益性などの観点によって選択されますが、
Kokoneでは、駅検索を使って頂いたユーザーに__インタースティシャル広告__というワンタイムの広告を恐れ多くも出させて頂く方針として、個人でも利用可能なSSPサービスを探しました。

下記の様なSSPサービスに連絡させて頂き、
審査を落ちまくった上、結果的に __[Adstir](https://ja.ad-stir.com/)__ というサービスと契約させて頂くことになりました。

|サービス|審査結果|
|:---|:---:|
|Google Adsense|審査NG😢(数十回トライ)|
|[Fluct](https://corp.fluct.jp/)|審査NG😢|
|[Adstir](Adstir)|審査OK🎉|
|MicroAd COMPASS|審査NG😢|
|GMO SSP|審査NG😢|

(Google Adsenseの利用申請は、リリースから何十回と提出し続けてきましたが、`コンテンツが不十分`とのメッセージで一生弾かれています。。。どなたか審査通すアドバイスあればぜひ教えてください🙇)

# 終わり

導入した結果については、また記事化してご報告できればと思っています！
まずは、いち個人開発サービスで無料運用が難しくなった点と、月額費用をペイするためにKokoneで利用した方法の共有までにでした！

今後ともKokoneをよろしくお願いします！
もっとご利用頂いてもっとヒーヒー言わせてください！！

https://kokone-app.com/about?utm_source=qiita&utm_medium=referral&utm_campaign=monetize-demands-bottom
推論性能を上げるテクニックに関する最近のLLM

推論性能を上げるテクニックに関するLLMの論文を2つ紹介します。

[1. 逆思考問題を解くことによる推論性能の向上「RevThink」](##逆思考問題を解くことによる推論性能の向上「RevThink」)
[2. マルチエージェントLLMトレーニングによる推論性能の改善「MALT」](##マルチエージェントLLMトレーニングによる推論性能の改善「MALT」)


## 逆思考問題を解くことによる推論性能の向上「RevThink」
### Reverse Thinking Makes LLMs Stronger Reasoners

**逆思考** とは、問いに対して答えを導くのではなく答えから問いを求めることです。小学校の算数のカリキュラムなどでも思考を鍛える方法としてで注目されいます。

例えば、次のようなものです
> 通常の問題： Aさんはリンゴを2個、Bさんは3個持っています。あわせていくつのリンゴがあるでしょう？

> 逆思考の問題： 5個のリンゴがあります。Aさんがリンゴを2つ持っていたらBさんはいくつもっているでしょう？

これをLLMに適応します。
上の例を使って、リンゴの合計が5ではなく6と推論してしまった場合、これを答えとして逆思考の問題を解くとBさんが4個のリンゴを持っていなければいけません。

**このような、順方向の推論と逆方向の推論の思考の一貫性や矛盾を扱うことでパフォーマンスの向上が見込めます。**

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/481cb770-7c0d-1992-6ad5-7e049a48f731.png)

#### Reverse-Enhanced Thinking (RevThink) 
LLMが逆思考を実行できるようなフレームワークがRevThinkです。具体的には教師モデルから順方向・逆方向の推論を収集してデータセットを拡張します。

:::note
1. **順方向の推論**　(2+3=5)
1. **質問から逆方向の質問の生成** (5=2+?)
1. **逆方向の質問から逆方向の推論** (5=2+3)
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/bd988606-6ac5-1845-2866-ae436c65a388.png)


これによってZero-shotのパフォーマンスと比べて平均 **13.53%** の向上が見られました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/1746645a-c9d3-49dc-1af7-c7b1a0132188.png)


## マルチエージェントLLMトレーニングによる推論性能の改善「MALT」
### MALT: Improving Reasoning with Multi-Agent LLM Training

LLMは通常、人間がその出力を評価して洗練させますが、複数のLLMが協調することで性能の向上が期待できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/e0ecdfb3-c7af-1cc4-5c47-24080c411363.png)

図のように、このモデルは**Llama** をベースとして、**ジェネレーター(Generator)** と **検証者(Verifier)**、**調整者(Refiner)** の3つの異種のLLMによるマルチエージェントが共同で働きます。

それぞれの簡単な役割は以下の通りです。

:::note
- **Generator： 質問に対する最初の答えの生成**
- **Verifier： 評価の提供**
- **Refiner： 最終的な出力のため、評価に応じて答えを統合**
:::

実際に、ベースラインに対して **7~14%** 改善が見られました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/986141/68e1a634-76aa-eb49-0b5a-16b39ae6e33c.png)



## 参考
### 各arXiv論文はこちらです。

- Reverse Thinking Makes LLMs Stronger Reasoners

https://arxiv.org/abs/2411.19865

- MALT: Improving Reasoning with Multi-Agent LLM Training

https://arxiv.org/abs/2412.01928

- DPOについて

https://qiita.com/jovyan/items/6767c9fd944a636fdf88
【VSCode】GitのBlameをエディタ内に表示する方法

`git.blame.editorDecoration.enabled`を`true`にすることでGitのBlameをエディタ内に表示できます。

```settings.json
{
  "git.blame.editorDecoration.enabled": true
}
```

![スクリーンショット 2024-12-14 23.57.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/eed0b5be-3edc-e946-7396-52d4ef147c5d.png)
（AI-900についてChatGPTに聞いてみた）ディープラーニングとは

AI-900を学習する過程で感じた疑問をChatGPTに教えてもらいました。この記事ではディープラーニングと多層ニューラルネットワーク（ディープラーニング）に関する会話をまとめます。ちなみに記事の大部分もChatGPTが書いてくれました。

---

## ディープラーニングとは？

**僕**: ディープラーニングとは、どういう技術なの？

**ChatGPT**: ディープラーニングでは、複数の層から構成されたニューラルネットワークを用いて、入力データから特徴を抽出し、予測を行うんだ。ネットワークが正しい予測をできるようにするためには、**順伝播**と**逆伝播**という二つの重要なプロセスを繰り返し行う必要があるんだ。


### 順伝播 (Forward Propagation)

順伝播は、入力データがネットワーク内を順に通過していく過程を指すよ。入力層から始まり、各隠れ層を経て最終的な出力層まで、データが伝わっていくんだ。各層では、入力データに重みを掛け、バイアスを加えて出力を計算する。この出力が最終的に予測結果となる。

### 逆伝播 (Backpropagation)

逆伝播は、出力層での誤差（予測と実際の差）を使って、ネットワーク全体の重みを調整するプロセスだよ。まず出力層で誤差を計算し、その誤差が前の層に（逆方向に）伝播されていく。各層で計算される誤差は、重みの更新に必要な勾配計算の為に使われるんだ。この勾配を使って、重みが少しずつ最適化され、ネットワークの精度が向上していくんだよ。逆伝播はバックプロパゲーションとも言うよ。

---

## 順伝播とは？

**僕**: 順伝播って具体的には、どういうプロセスのこと？

**ChatGPT**: 順伝播は、入力データがネットワークを通って出力されるプロセスだよ。例えば、3層のネットワークの場合、次のような流れで計算されるよ。

1. 入力データ $X$ を最初の層に流し込む。
2. 最初の層で行列演算を行って、次の層に出力を渡す。
3. このプロセスが繰り返され、最終的な出力 $Y$ が得られる。

このとき、各層では次の計算が行われるんだ。

$$
Y = X \cdot W + b
$$

ここで、$X$ は入力データ、$W$ は重み行列、$b$ はバイアス、$Y$ はその層の出力だよ。

---

## Activation関数とは？

**僕**: それぞれの層では、単に行列の計算だけが行われるだけ？

**ChatGPT**: 実は、行列計算の結果には**Activation関数**（活性化関数）を適用するんだ。これは、ニューラルネットワークに非線形性を加えるために使われる関数だよ。線形のままだと、ネットワークは単なる線形結合を繰り返すだけになってしまって、複雑なパターンを学習することができないからね。

よく使われるActivation関数には次のようなものがあるよ：

- **シグモイド関数**:
  $$ \sigma(x) = \frac{1}{1 + e^{-x}} $$

- **ReLU（Rectified Linear Unit）関数**:
  $$ \text{ReLU}(x) = \max(0, x) $$

これらの関数を使って、ネットワークに非線形性を持たせ、複雑な問題を解けるようにするんだ。

---

## 逆伝播とは？

**僕**: 逆伝播は、具体的には、どんなプロセスのこと？

**ChatGPT**: 逆伝播は、誤差をネットワークの各層に逆向きに伝えていくプロセスだよ。具体的には、ネットワークの最終出力と正解との誤差を計算して、その誤差を遡って各層の重みを調整するんだ。

例えば、3層のネットワークの場合、出力層から誤差を逆伝播していく方法は次のようになるよ。

1. **出力層の誤差 ($\delta_3$)**

$$
\delta_3 = \frac{\partial L}{\partial Y_3}
$$

出力層で誤差を計算するよ。

2. **2層目の誤差 ($\delta_2$)**

$$
\delta_2 = \delta_3 \cdot W_3^T \cdot \text{Activation}'(Y_2)
$$

出力層の誤差を使って2層目の誤差を計算するんだ。

3. **1層目の誤差 ($\delta_1$)**

$$
\delta_1 = \delta_2 \cdot W_2^T \cdot \text{Activation}'(Y_1)
$$

これで、1層目の誤差を計算するよ。

---

## 勾配計算と重みの更新

**僕**: 逆伝播で誤差を計算したら、次に重みを更新するの？

**ChatGPT**: そうだよ！誤差 $\delta$ を計算したら、それを使って勾配を計算して、重みを更新するんだ。**勾配降下法**を使って重みを調整するよ。

勾配降下法では、次のような式で重みを更新するんだ。

$$
W = W - \eta \cdot \frac{\partial L}{\partial W}
$$

ここで、$W$ は重み、$\eta$ は学習率、$L$ は損失関数、$\frac{\partial L}{\partial W}$ は重みに対する損失関数の勾配だよ。この更新を繰り返して、最適な重みを見つけ出すんだ。

---

### 勾配計算と誤差 δ の関係

**僕**: 勾配計算と誤差の $\delta$ はどんな関係があるの？

**ChatGPT**: いい質問だね！実は、勾配計算と重みの更新は誤差の $\delta$ と密接に関係しているんだ。

1. **誤差 $\delta$**: 各層で計算される誤差 $\delta$ は、その層の出力が損失関数にどれだけ影響を与えるかを示している。出力層の誤差から順に、各層で誤差を計算するんだ。

2. **勾配計算**: 誤差 $\delta$ は、勾配計算に使用され、重みの更新に使われる。このように、誤差 $\delta$ が勾配計算に関与し、その結果として重みが調整されるんだ。

例えば、1層目の重み $W_1$ の更新には、次のように誤差 $\delta_1$ が使われるよ：

$$
W_1 = W_1 - \eta \cdot X^T \cdot \delta_1
$$

ここで、$\delta_1$ は1層目の誤差、$X$ はその層への入力データだよ。**誤差 $\delta$ は勾配計算において不可欠な役割を果たしており、その結果として重みが更新される**んだ。

---

## ディープラーニングと多層ニューラルネットワーク

**僕**: ディープラーニングって、多層ニューラルネットワークを使った学習技術という意味で合ってる？

**ChatGTP**: はい、ディープラーニングは、**多層ニューラルネットワーク**とその学習を支える**バックプロパゲーション**という手法の組み合わせによって、強力な学習モデルを作り上げる技術のことを言うんだよ。

---

**僕**: 良く分かったよ。ありがとう！

**ChatGTP**: よかった！分かりやすかったなら嬉しいよ！もし他にも気になることがあったら、いつでも聞いてね！
最近GAになったSTUNnerについて調べてみた

# はじめに
色々Kubernetes周りのOSSを調べていたところ、STUNnerというKubenetes向けのWebRTC関連のOSSがGAになっていました。
気になったのでどういったOSSなのかを調べてまとめてみました。

https://medium.com/l7mp-technologies/stunner-goes-ga-the-journey-so-far-and-the-future-ahead-b3c4c800926b


# STUNnerとは
STUNnerはKubernetes向けに作成されたWebRTC用メディアGatewayです。
オーディオ・ビデオといったWebRTCストリームを仮想化をKubernetes内のmediaサーバへ流す役割を持っています。
L7mp Technologiesという4人の博士課程と1人の修士課程の5人チームの会社が主導して作っているようです。

https://docs.l7mp.io/en/v1.0.0/WHY/

https://l7mp.io/#/about


またCNCF landscapeにも登録されています。

https://landscape.cncf.io/?group=projects-and-products&view-mode=card&item=orchestration-management--service-proxy--stunner#app-definition-and-development--application-definition-image-build

## KubernetesとWebRTCの相性
KubernetesとWebRTCの組み合わせは以下の理由から相性が最悪とのこと
- Kubernetesは主にHTTP/TCPベースに設計されている- 
  - WebRTCはUDP/RTPベースで動作するためKubenetesの設計に適してなかった
- KubernetesのNAT
  - Kubernetsのデータプレーンには複数のNATが存在しておりWebRTCは複数のNAT変換に弱い
  - これによりUDP/RTPによる接続が切断されメディアサーバにたどり着けない


現状の解決策としてメディアサーバーPodをデプロイする際に`hostnetwork=true`にすることでNAT変換を回避できるが、Kubernetesのアンチパターンにあたってしまう。ref: [docs](https://kubernetes.io/docs/concepts/configuration/overview/)

STUNnerでは`hostnetwork=true`でメディアサーバPodを実行することなく、メディアトラフィックをKubernetes内に入れることができるとのこと。またSTUNnerはメディアGatewayとしての役割だけでなく、STUN/TURNサーバとしても使うことができる。

https://docs.l7mp.io/en/v1.0.0/WHY/

## STUNerのアーキテクチャ
STUNnerのアーキテクチャは以下のとおりです。

https://docs.l7mp.io/en/stable/CONCEPTS/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469304/bb65ee95-84a0-48a9-feed-4800fc73ac44.png)

Control planeとData planeに分かれています。一個ずつ見ていきます。

Control plane

- Gateway API: オーディオ・ビデオといったメディアトラフィックを受け入れるための設定方法を記述するリソースの集合体
  - GatewayClass: 設定階層の一番トップ
  - GatewayConfig: STUNner全般の設定を担う
  - Gateway: 各TURNサーバリスナーのポートとプロトコルを定義
  - UDPRoute: クライアントトラフィックの転送先バックエンドサービスを指定
- STUNner Gateway Operator: Gateway APIリソースの監視をする


Data plane
- stunnerd pods
  - pion/turnというGoのWebRTCフレームワークベースのTURNサーバを実装
  - Gateway事に別個のDeploymentとして展開
  - バックエンドサービスへのパケット転送
- LoadBalancer Service
  - Gateway事に作成される
  - stunnerd podのTURNリスナーを外部に公開する

こう見るとIngressをWebRTC版に拡張したように見える。(実際はもっと複雑なのかも?)

# まとめ
今回はたまたま見かけたSTUNnerを軽く調べてみました。WebRTCはちょこちょこ調べている程度の知識しかありませんでしたが、STUNnerのドキュメントをとうしてKubernetesとWebRTCの相性について学ぶことができました。
次の記事ではSTUNnerを使ったdemoを動かしてみようと思います。

# 参考文献
https://medium.com/techbeatly/kubernetes-networking-fundamentals-d30baf8a28c8

https://medium.com/l7mp-technologies/deploying-a-scalable-stun-service-in-kubernetes-c7b9726fa41d

https://www.youtube.com/watch?v=iY1xoItHcto
Railsの実例実装でわかる❗️バリデーションをカスタムしてハッピーハッピーハッピ〜ハピハピハピハピハピ〜になろう❗️😸

この記事は [ex-crowdworks Advent Calendar 2024](https://qiita.com/advent-calendar/2024/ex-cw)の15日目の記事です。

# はじめに
今年、株式会社クラウドワークスを退職した@nisyuuです。珈琲は豆を挽くところから作っています。
エンジニアとしてクラウドワークステック（旧クラウドテック）というフリーランスと企業をマッチングするエージェントサービスを開発していました。

Railsには、データが正しい形で保存されるようにするためのバリデーション機能があります。例えば、入力が必須であることや、同じ値が重複しないことを簡単にチェックできます。
ただし、標準の機能だけでは対応できない特別な条件を追加したい場合、**カスタムバリデーター**を作成する必要があります。

本記事では、カスタムバリデーターの仕組みと作り方をわかりやすく解説します。

# カスタムバリデーターの実装方法

カスタムバリデーションを実装する方法は大きく分けて2つあります。

## 1. モデル内にカスタムメソッドを定義する

比較的簡単なバリデーションは、モデル内にメソッドを定義して実装できます。この方法は特定のモデルだけで利用する場合に適しています。

### 実装例: 禁止された単語をチェックする

以下は、投稿内容に禁止された単語が含まれている場合にエラーを発生させる例です。

```ruby
class Post < ApplicationRecord
  validate :content_cannot_include_restricted_words

  private

  def content_cannot_include_restricted_words
    restricted_words = %w[禁止語句 不適切]
    if restricted_words.any? { |word| content&.include?(word) }
      errors.add(:content, "この投稿には禁止された言葉が含まれています。")
    end
  end
end
```

### 解説

- `validate`メソッドでカスタムメソッド`content_cannot_include_restricted_words`を呼び出しています
- 条件を満たさない場合、`errors.add`でエラーメッセージを追加します



## 2. 再利用可能なカスタムバリデータークラスを作成する

複数のモデルで同じバリデーションを利用する場合は、専用のクラスを作成する方法が適しています。この方法では、`ActiveModel::EachValidator`を継承したクラスを作ります。

### 実装例: 許可されたメールアドレスのドメインを制限する

1. **バリデータークラスを作成**

`app/validators`ディレクトリを作成し、その中にクラスファイルを追加します。

例: `app/validators/email_domain_validator.rb`

```ruby
class EmailDomainValidator < ActiveModel::EachValidator
  def validate_each(record, attribute, value)
    allowed_domains = options[:domains] || []
    domain = value&.split('@')&.last

    unless allowed_domains.include?(domain)
      record.errors.add(attribute, "許可されたドメイン（#{allowed_domains.join(', ')}）のメールアドレスを使ってください。")
    end
  end
end
```

### 解説

- このクラスは`ActiveModel::EachValidator`を継承し、1つの属性（フィールド）に対してバリデーションを行います
- `options`を通じて、許可するドメインのリストを外部から渡せるようにしています

2. **モデルで使用**

作成したバリデータークラスをモデル内で利用します。

```ruby
class User < ApplicationRecord
  validates :email, email_domain: { domains: %w[example.com test.com] }
end
```

### 解説

- `validates`メソッドにカスタムバリデーター`email_domain`を指定しています
- オプションで許可するドメインを渡しています



# カスタムバリデーターのテスト

バリデーションが正しく動作することを確認するため、テストを作成します。ここではRSpecを使った例を示します。

## テスト例

```ruby
require 'rails_helper'

describe User, type: :model do
  it '許可されたドメインのメールを受け入れる' do
    user = User.new(email: 'test@example.com')
    user.validate
    expect(user.errors[:email]).to be_empty
  end

  it '許可されていないドメインのメールを拒否する' do
    user = User.new(email: 'test@invalid.com')
    user.validate
    expect(user.errors[:email]).to include("許可されたドメイン（example.com, test.com）のメールアドレスを使ってください。")
  end
end
```

## 解説

- 2つのテストケースを用意しています：
  1. 許可されたドメインのメールアドレスがエラーにならないことを確認
  2. 許可されていないドメインのメールアドレスがエラーになることを確認

# おわりに

Railsのカスタムバリデーターを使うことで、特定の要件に応じた柔軟なデータ検証が可能になります。
簡単な要件であればモデル内にメソッドを定義する方法が適していますが、再利用性が求められる場合はカスタムクラスを作成すると便利です。

これであなたもカスタムハッピーに！😼

![ハッピーハッピーハッピー猫](https://i.makeagif.com/media/2-06-2024/4OUbQn.gif)
基本情報技術者試験の合格体験記兼忘備録

# 私の試験結果
A試験770点
B試験715点
一発合格
勉強期間は3か月

# 勉強法
## A試験対策
インプットはさらっと終わらせて時間をかけすぎない。
Youtubeで以下の無料解説動画を1本見るだけでいい。

【2024年】基本情報技術者試験の科目Aを12時間で完璧に理解
https://www.youtube.com/watch?v=oqaBEnhIxk0

動画を見終わったら過去問道場で直近5年分の過去問とサンプル問題を解く。

基本情報技術者試験過去問道場
https://www.fe-siken.com/fekakomon.php

**無料の過去問が豊富なので教材を買う必要はまったくない。**
最初は問題の内容がわからなくても、解説を読んで調べたりしてくと5年分が終わるころには初見の問題でも8割解けるようになった。


## B試験対策
プログラミング経験の有無で難易度が変わると思う。
これもYoutubeの動画が大変参考になった。

【科目B】アルゴリズム問題をたった1動画で対策_基本情報技術者試験
https://www.youtube.com/watch?v=wFpyeWto8Og

サンプル問題を解いて疑似言語やトレースに慣れるたらOK。
解くスピードも意識しないと本番の試験で時間が足りなくなるので注意。

私は多少プログラミングの経験があったのでサンプル問題を2周したら合格できた。
B試験は**プログラムを読解する能力**を問われていると感じた。

安全策を取るなら、評価が高いB試験対策本を買っても良かったかもしれない。

### 補足
最短で基本情報技術者試験に挑戦する必要がないのであれば、寄り道してプログラミングの勉強をしてもいいと思う。
paizaがプログラミング言語の初歩から試験に登場するアルゴリズムまで勉強できるからお勧め。
https://paiza.jp/works

学校でプログラミングが必修化したし、B試験の8割がアルゴリズムになったのも「国民みんなプログラミングできるようになろうね」施策の一つなんだろうというのが個人の感想。

# モチベーション管理
## 試験日を決める
ゴールや期限が決まってないと気持ちが動かないのでとりあえず試験日を決めるた。
試験日は後から変更可能なので、勉強の進捗が間に合わなければ先延ばしできる。
逆にスムーズに進んだら試験日を前倒しできる。私も前倒しした。

### 余談
試験会場の予約が埋まっていてもキャンセルが発生することもある。
特に試験直前の3、4日前がキャンセル待ちのねらい目。

## スケジュールを立てる
試験日までに10年分の過去問を終わらせる。みたいに目標を設定し、目標を達成するために必要な勉強量を考えた。
試験までの１週間のスケジュールを立てるのが理想。

（例）A試験対策として3か月以内に10年分の過去問を終わらせる
　→1週間で1年分解く
　→1年分の過去問は60～80問なので1日10問程度は解く必要がある

## 3分でいいから勉強の習慣をつける
どんなに忙しくても通勤時間や休憩時間に3分だけスマホで過去問を解くみたいに勉強を習慣化した。
試験勉強が生活の一部になれば、勉強のモチベーションが上がる。


# まとめ
A試験は過去問で出たとこ覚えればOK
B試験は解き方覚えてスピード意識

みんな試験頑張ってね！
Github Copilot 提案してくれない or Tabによる承諾ができない時の対処法

## はじめに
日々の活動、ご苦労様です!!
私、遅ればせながらCopilotデビューしました !! :clap::clap::clap::clap::clap:

その矢先にドン詰まりしましたので、対処ログを残します。

本記事の内容は下記2点です
最後までお読みいただけるよう努めます！
- 提案してくれない時の対処法
- Tabキーで承諾出来ない時の対処法



## 提案してくれない時の対処法
インストールしたては提案してくれたんですが、何か余計なことをしたのかフル無視されたので調べてみました!

### 原因
設定漏れです!
提案を希望する言語リストに、使用言語（Typescript）が抜けていました

### 解決策
vscodeの設定画面にて、Copilotの提案を受けたい言語を設定します。
もしかしたらデフォルトで色々有効になっていたのかもですが、自分の場合ほぼ何も設定されていなかったので、非常に苦しみました :relaxed:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/8e66cfd2-be3d-f86a-facc-d7d63beb10f7.png)

言語識別子は下記リンク先に掲載されてます〜

https://code.visualstudio.com/docs/languages/identifiers



## Tabキーで承諾出来ない時の対処法
こちらも非常に悩まされた問題です!!
Tabキーで承諾言うから押してるのに、提案消えるしTab入るという、ね?
顔歪みますよね 笑

キーボードショートカットの開き方(mac): cmd + k → cmd+s

### 原因
ショートカットの設定が他の拡張機能などとの兼ね合いで動かないこと。
故に、その競合を修正すればOKです。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/9f744515-0a85-b28b-be63-059479966977.png)


### 解決策1
こちらを参考に試してみてください。

https://wp.kobore.net/%E6%B1%9F%E7%AB%AF%E3%81%95%E3%82%93%E3%81%AE%E6%8A%80%E8%A1%93%E3%83%A1%E3%83%A2/post-13786/

### 解決策2
こちらは私が試した方法になりますが、「承諾」機能をTabではなく別のキーに設定する方法です。
対象「インライン候補を採用する」にカーソルを合わせると左の列に編集アイコンが表示されるので、割り当てるキーを設定してください。
ちなみに私は「1」に設定しました :triumph:

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606316/12802139-0adf-12c7-f005-da4eed6926b6.png)


## 終わりに
最後までお読みいただきありがとうございます!!
サっと使えるもんだと思い込んでいたので早々に折れかけましたが、なんとか通常運転まで漕ぎ着けてよかったです :joy:
1ヶ月はフリーなので使い込むつもりですが、他のAI・LLMも試して自分のベストを見つけたいと思います!

https://x.com/yokosu_k/status/1865326312015241643

### 追伸
アドカレ7記事目終わり〜
実はサンタ生やしてます

:santa_tone1::santa_tone1::santa_tone1::santa_tone1::santa_tone1:
:santa_tone1::santa_tone1:
MacでVirtualBoxを使うときにコピペができるようにする手順

# VirtualBoxにインストールしたUbuntuへコピペがしたい
　VirtualBoxにUbuntuをインストールし、Dockerを使えるように設定を行おうとした。dockerだけなら手作業でも気合いでできそうなコード量だが、docker-composeはさすがに厳しい(https:/~とか面倒すぎる)。ネットの記事でコピペできる方法を探したが、GUIを使った場合の説明がほとんどでCUIでやっているケースには当てはまらない。
　ということで、MacでVirtualBoxの仮想環境でコマンドがコピー&ペーストできるようになるまでをまとめて記録しておく。
 ## 環境
 MacOS Sequoia 15.1.1
 Oracle VirtualBox バージョン 7.1.2
-オペレーティングシステム:Ubuntu(ARM64bit)
 ## Step1 IPアドレスを確認する
 VirtualBoxで以下のコマンドを入力
  ```ubuntu:
$ ip a
```
`enp0s8:`という部分にIPアドレスが書かれているのでメモしておく。
(192.168.~となっている人が多い？)
`enp0s8:`の表示が出ていない場合は、Oracle VirtualBox マネージャーから「設定」を開き、「ネットワーク」のアダプターを「ブリッジアダプター」にしておく
 ## Step2 SSHサーバをインストールする
 VirtualBoxで以下のコマンドを一行ずつ入力
 ```ubuntu:
$ sudo apt update
$ sudo apt install openssh-server
$ sudo ufw enable
$ sudo ufw allow 22
$ sudo ufw reload
```
SSHサーバが起動していることを確認
 ```ubuntu:
$ sudo systemctl status ssh
```
以下のようなものが出ていればOK
 ```ubuntu:
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/usr/lib/systemd/system/ssh.service; disabled; preset: ena>
     Active: active (running) since Sat 2024-12-14 13:26:37 UTC; 17min ago
TriggeredBy: ● ssh.socket
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 1679 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 1680 (sshd)
      Tasks: 1 (limit: 2212)
     Memory: 1.9M (peak: 2.9M)
        CPU: 69ms
     CGroup: /system.slice/ssh.service
             └─1680 "sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups"
```
## Step3 Macのターミナルからssh接続する
ターミナルを開き、メニューバーから「シェル」>「新規リモート接続」を選択する。そして、サービスは「ssh」にして、サーバは下の「+」ボタンをクリック。
![screenshot2024-12-1422_59_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523017/b28e7d6e-e7f7-2a9f-097e-bb42faca350f.png)
すると、IPアドレスを入力するように求められるので、先ほどメモしたIPアドレスを入力する。
![screenshot2024-12-1422.59.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523017/9f31a034-cb2c-0224-f95c-839b6a1d8f41.png)
最後にUbuntuにログインする際のユーザ名を入力して「接続」ボタンをクリックする。
![screenshot2024-12-1423_09_20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523017/d9f4173a-33ea-1918-2396-47771b60cbb5.png)
すると、ターミナルのウィンドウが開き、VirtualBoxで起動をした場合と同じようにパスワードを求められる。

![screenshot2024-12-1423.09.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3523017/12b8d592-aa3a-0491-812d-40ef67d9300f.png)
あとは、パスワードを入力すればターミナル上でUbuntuが操作でき、コピペも可能になる。