OmniAICreator/Qiita-1.07M huggingface dataset:
【プログラミングが楽しくなる！】VSCode拡張機能ランキング

# はじめに
皆さん、コードを書く時エディタとしてVSCodeを使っている方が多いと思います。


![スクリーンショット 2023-08-25 20.04.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/f97b165c-80aa-b178-cf2e-b29114c4d8e1.png)

その際、コード補完やコード整形のために**拡張機能**を入れますね！
![スクリーンショット 2023-08-25 19.59.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/1926d2bf-8b76-d960-bcd0-b1b0119b442f.png)

ただ拡張機能の中には「エンタメ」を目的としたものがあります！
そこで、**プログラミングが楽しくなるVSCodeの拡張機能ランキング**をご紹介します！

# 第3位 『Power Mode』

![スクリーンショット 2023-08-25 2.00.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/ee081963-10c8-4fe9-07bf-3f07facf7deb.png)
書いた時に<b>「小さな爆発とコンボ」</b>が演出されます！

![スクリーンショット 2024-02-23 20.03.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/078f5774-27d1-db1b-47eb-3851e341cf82.png)
ただ1文字書いただけでコンボになるので、**コメントアウトしただけでも凄まじいコンボが続きます。**
![スクリーンショット 2024-02-23 20.06.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/4215e7e8-82d3-20c0-13fe-0ac565c4eb8d.png)

# 第2位 『Indent-Rainbow』

![スクリーンショット 2023-08-25 2.02.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/fc75e2cf-084c-5df9-d348-aeb2f02dcf52.png)

その名の通り<b>「インデントしたところにカラフルな色」</b>が塗られます！

# 第1位 『line-erase-game』
![スクリーンショット 2023-08-25 3.59.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/4a13c05d-3381-c030-3ed1-f8e4f4945e5c.png)

<b>書いていたコードを全消ししてテトリスが楽しめます！</b>
![スクリーンショット 2024-02-23 20.13.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/cb00d6fb-a4a9-5146-18db-003641dab081.png)
もほや拡張「機能」かどうか怪しいですが...
<b>コードを全消ししてしまうので、全てがどうでもよい時に使いましょう！</b>

# 最後に
皆さんもおすすめの拡張機能があったらコメントお願いします！

# 告知
TikTokで「プログラミングやってる人しか分からないネタ動画」をあげてます！ぜひご覧ください！↓
https://www.tiktok.com/@jimba_games

![スクリーンショット 2023-10-28 20.02.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3574599/6ecc0e9e-8a20-0772-da6e-644a05280e8b.png)
PlunkerでPhaser.Physics その5

# 概要
Plunkerで、Phaser.Physicsやってみた。
フリクションのテストです。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/306b960c-d08b-031e-9698-837efb528ee8.png)

# サンプルコード

```

var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { 
    create: create, 
    render: render 
});
function create() {
    game.stage.backgroundColor = '#124184';
    game.physics.startSystem(Phaser.Physics.BOX2D);
    game.physics.box2d.gravity.y = 500;
    game.physics.box2d.setBoundsToWorld();

    var rectangle1 = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX - 80, 150, 0);
    rectangle1.setRectangle(600, 15, 0, 0, Math.PI / 12);
    rectangle1.static = true;
    
    var rectangle2 = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX + 80, 330, 0);
    rectangle2.setRectangle(600, 15, 0, 0, -Math.PI / 12);
    rectangle2.static = true;
    
    var rectangle3 = new Phaser.Physics.Box2D.Body(this.game, null, game.world.centerX - 80, 510, 0);
    rectangle3.setRectangle(600, 15, 0, 0, Math.PI / 12);
    rectangle3.static = true;
    
    var wall1 = new Phaser.Physics.Box2D.Body(this.game, null, 655, 230, 0);
    wall1.setRectangle(20, 50, 0, 0, 0);
    wall1.static = true;
    
    var wall2 = new Phaser.Physics.Box2D.Body(this.game, null, 145, 410, 0);
    wall2.setRectangle(20, 50, 0, 0, 0);
    wall2.static = true;
    
    var square1 = new Phaser.Physics.Box2D.Body(this.game, null, 50, 30, 2);
    square1.setRectangle(20, 20, 0, 0, 0);
    square1.friction = 0.4;
    
    var square2 = new Phaser.Physics.Box2D.Body(this.game, null, 100, 30, 2);
    square2.setRectangle(20, 20, 0, 0, 0);
    square2.friction = 0.3;
    
    var square3 = new Phaser.Physics.Box2D.Body(this.game, null, 150, 30, 2);
    square3.setRectangle(20, 20, 0, 0, 0);
    square3.friction = 0.2;
    
    var square4 = new Phaser.Physics.Box2D.Body(this.game, null, 200, 30, 2);
    square4.setRectangle(20, 20, 0, 0, 0);
    square4.friction = 0.1;
    
    var square5 = new Phaser.Physics.Box2D.Body(this.game, null, 250, 30, 2);
    square5.setRectangle(20, 20, 0, 0, 0);
    square5.friction = 0;
}
function render() {
    game.debug.box2dWorld();
}




```

# 成果物


https://embed.plnkr.co/plunk/FdljXQNLSJj7fGrm


以上。
PlunkerでPhaser.Physics その4

# 概要
Plunkerで、Phaser.Physicsやってみた。
マウスで、オブジェクトにちょっかい出せます。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7818dc74-20b9-6374-8822-00bb7d72f0dc.png)

# サンプルコード

```
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { 
    create: create, 
    render: render 
});
function create() {
    game.stage.backgroundColor = '#124184';
    game.physics.startSystem(Phaser.Physics.BOX2D);
    game.physics.box2d.gravity.y = 400;
    game.physics.box2d.restitution = 0.8;
    game.physics.box2d.setBoundsToWorld();
    for (var i = 0; i < 10; i++)
    {
        var ball = new Phaser.Physics.Box2D.Body(this.game, null, game.world.randomX, 0);
        ball.setCircle(16);
        ball.bullet = true;
    }
    var ground = new Phaser.Physics.Box2D.Body(this.game, null, 0, 200);
    ground.addEdge(0, 0, 100, -100);
    ground.addEdge(100, -100, 200, -50);
    ground.addEdge(200, -50, 300, -50);
    ground.addEdge(300, -50, 500, -85);
    ground.addEdge(500, -85, 600, -10);
    ground.addEdge(600, -10, 700, -40);
    ground.addEdge(700, -40, 800, 0);
    game.input.onDown.add(mouseDragStart, this);
    game.input.addMoveCallback(mouseDragMove, this);
    game.input.onUp.add(mouseDragEnd, this);
}
function mouseDragStart() {
    game.physics.box2d.mouseDragStart(game.input.mousePointer);
}
function mouseDragMove() {
    game.physics.box2d.mouseDragMove(game.input.mousePointer);
}
function mouseDragEnd() {
    game.physics.box2d.mouseDragEnd();
}
function render() {
    game.debug.box2dWorld();
}




```

# 成果物

https://embed.plnkr.co/plunk/LU3JJzJL8ynVLYCz


以上。
docker pull elixir 〜dockerでElixirのイメージを取得する〜

# Brightの対象
Webアプリ開発 Elixir > クラス1 > Elixir環境構築 > ローカルPC > docker pull elixir

# dockerでElixirのイメージを取得する

```sh
$ docker pull elixir
```

これで最新のElixirのイメージを取得できます

# バーション指定する
1.14.5-otp-24を取得
```sh
$ docker pull elixir:1.14.5-otp-24
```

# iexを起動する
```sh
docker run -it  elixir
```

バーション指定は
```sh
docker run -it  elixir:1.14.5-otp-24
```
で起動できます
WayPonDEV YDLIDAR Tmini Pro lidar 360 

# はじめに

YDLIDAR Tmini Pro lidar 360 を購入後、デモアプリを起動するまでの流れの覚書です。

![IMG_7916.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/1b9466f7-9a74-c613-2325-bf093ac20c93.jpeg)

https://www.amazon.co.jp/gp/product/B0BFHB36ST/ref=ppx_yo_dt_b_asin_title_o01_s00?ie=UTF8&psc=1



# 手順

## 0.HPへ
https://www.ydlidar.com/

## 1.driverのダウンロード

### HP > Downloads&Support > USB adapter boar driver
 
![スクリーンショット 2024-02-23 19.40.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8ece8d2f-8d8c-cec8-94b1-5d4e5da360de.png)

![IMG_7918.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/0c50c5b6-cf92-f32b-3430-787640e0735c.jpeg)


## 2.viewerのダウンロード

HP > Downloads&Support > LidarViewer-V0.3.5

![スクリーンショット 2024-02-23 19.40.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/8ece8d2f-8d8c-cec8-94b1-5d4e5da360de.png)

![IMG_7914.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/544acb11-66af-b69b-7675-6b73031113e8.jpeg)

![IMG_7915.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/43766/6bb5e1ee-d39a-a123-0fc4-72a8c0cae767.jpeg)
Vimを覚える 【vimtutor Lesson 3】

# はじめに

前回の記事はこちらです。

https://qiita.com/kohki_takatama/items/5d7e24debd014df7241b

# Lesson 3.1

<font color="LimeGreen">`p`でペースト！</font>です。

Vimでは、「削除」がすべて「切り取り」の役割を果たします。

なので、「削除（切り取り）」⇒「貼り付け」が可能です。

# Lesson 3.2

<font color="LimeGreen">`r`で「置換」！</font>です。

`r`で置換できるのは１文字だけです。

文字単位などで置換したい場合は、おそらく後に出てきますが`ciw`などを使用します。

# Lesson 3.3

<font color="LimeGreen">`ce`で「単語の終わりまでを置換」！</font>です。

`r`と違い、今いるカーソルから単語の終わりまでを置換します。
置換というか削除してinsertモードにします。

`cc`コマンドについても触れられています。
行全体の置換（削除してinsert）ですね。

余談ですが、`cc`と`S`は全く同じ機能を持つコマンドです。
また、`s`は１文字を削除し、insertに入ります。

# Lesson 3.4

<font color="LimeGreen">`c`にも数字や`$`を組み合わせられるよ！</font>です。

`c3`で「３文字削除しインサート」
`c$`で「行末まで削除しインサート」

# Lesson 3 修了！

おつかれまでした！

# おわりに

今回は短かったですね。

`c`を使った置換はVimならではという感じがしてテンション上がります笑

次回記事はこちら！

https://qiita.com/kohki_takatama/items/1fe6d693bfcd90abf2a3
unity ECSでキャラクターをマウスで取得（掴んだり）

![Something went wrong]()

unityのECSを使って、キャラクターにマウスカーソルを合わせると色が変わり、クリックで掴んで移動する機能を再現しました。

一から再現できるわけもなく、UNITY公式のサンプルPJからのリバースエンジニアリングです。
https://github.com/Unity-Technologies/EntityComponentSystemSamples

Unity physicsの中に色々とサンプルプロジェクトが入っていますが、7.Queryの中に入っているQuery - Custom Collectorを開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715582/fc9a51d8-b8ea-dd9c-1e46-63eb0e911272.png)

色々と漁っていると、オブジェクト（Entitiy）にPhysics BodyやPhysics shapeなるコンポーネントがついていることがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715582/c3cfe36d-8cb7-2959-d0bc-0f2a396834ef.png)

また、サブシーン内のPhysics Settingsには、
Mouse Pick Authoring
Mouse Hover Authoring
というスクリプトがアタッチされています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715582/b967fe42-b82d-e22e-9d7f-870d80db47d8.png)

その他いくつかのスクリプトも使いますが、整理すると、以下7スクリプトを用いる必要があります。
（Mouseというようなフォルダを作って中に置いています。）
InitializeSamples.cs
MouseHoverAuthoring.cs
MouseHoverSystem.cs
MousePickAuthoring.cs
MousePickSystem.cs
MouseSpringSystem.cs
PhysicsSamplesExtensions.cs


InitializeSamples.csが無いと、マウスがクリックしたときに掴んだり、掴まなかったりと、挙動が安定しません。
"Application.targetFrameRate = 60;"
というコードが中に記述されており、1フレーム内でクリックが確実に検知できるようになっているようです。負荷のOtherが大きくなって、16msぐらいかかっているように見えて最初？と思いましたが、強制的にフレームレートを固定しているようです。

以上で完了です。
Physics BodyやPhysics Shapeが見つからないときは、
Unity Physics > Samples > Custom Physics Authoring
をimportしましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3715582/31b2de40-cc31-1195-f9ab-405d38cb449b.png)

ここから色々工夫すれば、Entitiyをマウスクリックで取得するプログラムが色々作れるはずです。

PS：
日曜プログラマーとしてゲームを作ってます。
Twitterに記録を残していってるので、是非フォローください。
Oracleで引数を受け取りテーブルを返す関数

## やりたいこと
・Oracleの関数
・パラーメータを受け取り
・テーブルを返す

## 実現結果のイメージ
```sql
select * from high_price_books_title(1500);
```
| ID | TITLE | PRICE |
|:--:|:--:|:--:|
| 1| 永遠のゼロ | 1600 |
| 3| 敗者のゲーム | 2000 |

## 前提
```sql
select * from book;
```
| ID | TITLE | AUTHOR | PRICE |
|:--:|:--:|:--:|:--:|
| 1| 永遠のゼロ | 百田尚樹 | 1600 |
| 2| 風の歌を聴け | 村上春樹 | 1200 |
| 3| 敗者のゲーム | チャールズ・エリス | 2000 |

## 実装方法
### TYPE（関数が出力するテーブルの型の定義が必須）
```sql
CREATE OR REPLACE TYPE t_book_title_record AS OBJECT (
    id NUMBER,
    title VARCHAR2(256),
    price NUMBER(10, 0)
);
/

CREATE OR REPLACE TYPE t_book_title_table IS TABLE OF t_book_title_record;
/
```


### FUNCTION
```sql
CREATE OR REPLACE FUNCTION high_price_books_title(p_price NUMBER)
RETURN t_book_title_table IS
    v_ret t_book_title_table := t_book_title_table();
BEGIN
    SELECT 
        t_book_title_record(
             id
            ,title
            ,price
          )
    BULK COLLECT INTO v_ret
    FROM book
    WHERE price > p_price;

    RETURN v_ret;
END;
/
```
[Swift] @escapingのないクロージャ引数でも循環参照が起こる例

# はじめに

`@escaping` なクロージャで `self` を強参照すると循環参照の危険があるのはご存知の方も多いでしょう。
以下は `@escaping` なクロージャで循環参照が起こる例です。

```swift
Main().main()

class Main {
    let test = Test()
    var value = 0
    
    deinit { print("deinit") } // 呼ばれない
    
    func main() {
        test.set {
            self.value += 1
        }
    }
}

class Test {
    var closure: (() -> Void)?
    
    func set(closure: @escaping () -> Void) {
        self.closure = closure
    }
}
```

この例では `Test.set(closure:)` が受け取ったクロージャをプロパティに保存しているため `@escaping` がついています。なので循環参照を回避するために `[weak self]` や `[unowned self]` をつけて `self` を弱参照する必要があります。

```diff_swift
    func main() {
-       test.set {
-           self.value += 1
+       test.set { [weak self] in
+           self?.value += 1
        }
    }
```

では、`@escaping` が**ついてない**クロージャ引数であれば循環参照の危険はないのでしょうか？

# Optionalなクロージャ引数

`Test.set(closure:)` の引数をOptionalに変えてみましょう。

```diff_swift
Main().main()

class Main {
    let test = Test()
    var value = 0
    
    deinit { print("deinit") } // 呼ばれる？
    
    func main() {
        test.set {
            self.value += 1
        }
    }
}

class Test {
    var closure: (() -> Void)?

-   func set(closure: @escaping () -> Void) {
+   func set(closure: (() -> Void)?) {
        self.closure = closure
    }
}
```

すると `@escaping` が消えてしまいました。この場合 `@escaping` をつけるとコンパイルエラーになります。
`@escaping` がないということは、このコードは循環参照しないのでしょうか？

実行してみれば分かりますが、このコードは**しっかり循環参照します**。

# なぜ `@escaping` がつかないのか

`@escaping`がつかないのは引数が クロージャ型 ではなく Optional型 だからです。
こう書くと分かりやすいかも知れません。

```swift
    func set(closure: Optional<() -> Void>)
```

敢えてここに `@escaping` を書こうとすると以下のコンパイルエラーが出ます。

> Closure is already escaping in optional type argument
> 訳：クロージャはOptional型の引数で既にエスケープされています

「既にエスケープされている」とはどういうことでしょうか？
Optionalの内部を理解するために、`Optional<() -> Void>` 型を `MyOptional` という名前で独自に定義してみましょう。

```swift
class Test {
    var closure: MyOptional = nil
    
    func set(closure: MyOptional) {
        self.closure = closure
    }
}

enum MyOptional: ExpressibleByNilLiteral {
    case some(() -> Void)
    case none
    
    init(_ some: @escaping () -> Void) {
        self = .some(some)
    }
    
    init(nilLiteral: ()) {
        self = .none
    }
}
```

`MyOptional.init(_:)` の引数が `@escaping` になっていますね。
ここで、`Test.set(closure:)` を呼ぶ側のコードを見てみましょう。

```swift
    func main() {
        test.set(closure: MyOptional {
            self.value += 1
        })
    }
```

ここまで来れば分かるはず、このクロージャがエスケープされるのは `MyOptional` での話であって、`Test` には無関係だということです。
なので `Test.set(closure:)` の方には `@escaping` はつきません。

# まとめ

Optionalなクロージャは `@escaping` がなくてもエスケープされる可能性があるため、強参照しないよう注意しましょう。
Optionalなクロージャを引数に持つ身近なものとして、[UIAlertAction](https://developer.apple.com/documentation/uikit/uialertaction/1620097-init)などがあります。
Pythonを使ったランチェスターモデルの計算（１）

# ランチェスターモデルの概要
1914年にフレデリック・ランチェスターが著作で発表したもの。戦争において、戦闘員の損耗過程を記述した数理モデル。
## ランチェスターの一次則
古典的な弓矢や剣を使った地上戦や霧や地形で見通しの効かない状況での戦闘を再現したモデル。戦闘を一騎打ちの集合と捉えている。
$$ \frac {dx}{dt}=-c_y$$ $$ \frac {dy}{dt} =-c_x$$

$c_x,c_y$は互いの軍の武器性能を表現している。
自軍の戦闘員の増加率は相手の武器性能に負比例することを表している。
上記の連立微分方程式を解くと以下の解が得られる。

$$x(t)=x_0-c_yt$$ $$y(t)=x_0-c_xt$$

## ランチェスターの二次則
１人で複数の敵を同時に攻撃することを仮定する。現代的な小銃や機関銃による歩兵戦闘、戦車による機甲戦闘に該当する。

$$ \frac {dx}{dt}=-c_{y2}y$$ $$ \frac {dy}{dt} =-c_{x2}x$$

$c_{x2},c_{y2}$は互いの軍の武器性能を表現している。
戦闘員の増加率は相手の武器性能と戦闘員数の積に負比例することを表している。

上記の連立微分方程式を解くと、以下の解が得られる。
$$ x(t)=\frac{1}{2}\biggl(x_0-\sqrt{\frac{c_{x2}}{c_{y2}}}y_0\biggr)exp(\sqrt{{c_{y2}c_{x2}}}t)+\frac{1}{2}\biggl(x_0+\sqrt{\frac{c_{x2}}{c_{y2}}}y_0\biggr)exp(-\sqrt{{c_{y2}c_{x2}}}t) $$ $$ y(t)=\frac{1}{2}\biggl(\sqrt{\frac{c_{y2}}{c_{x2}}}x_0-y_0\biggr)exp(\sqrt{{c_{y2}c_{x2}}}t)+\frac{1}{2}\biggl(\sqrt{\frac{c_{x2}}{c_{y2}}}x_0+y_0\biggr)exp(-\sqrt{{c_{x2}c_{y2}}}t) $$

# シミュレーション
pythonを利用して、上記の連立微分方程式を計算する。
各法則の関数odeLan1として定義し、scipy.integrateのsolove_ivp用いて関数を計算する。
各軍の初期戦力は、(x0,y0)=(5,10)としている。
武器性能は、(cx,xy)=(1,1)と(4,1)としている。

## 一次則の数値計算
```python
#ランチェスター1次則の定義
def odeLan1(t,z,cx,cy):
    dx = -cy
    dy = -cx
    return [dx,dy]

#戦力の定義
x0, y0 = 5, 10

#武器性能 (cx,cy)=(1,1)
Tend = 1 #シミュレーション時間
cx, cy = 1.0, 1.0
sol = solve_ivp(odeLan1, t_span=[0,Tend], y0=[x0,y0], args=(cx,cy), dense_output=True)
tc1 = np.linspace(0, Tend, 100)
yc1 = sol.sol(tc1)

#武器性能 (cx,cy)=(3,1)
Tend = 1 #シミュレーション時間
cx, cy = 4.0, 1.0
sol = solve_ivp(odeLan1, t_span=[0,Tend], y0=[x0,y0], args=(cx,cy), dense_output=True)
tc2 = np.linspace(0,Tend,100)
yc2 = sol.sol(tc2)
```
## 一次則の計算結果
![Lancherter_Order11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511532/9a9bc7a3-66c9-960d-b723-2038464ab5bb.png)

両軍ともに直線的に戦力が減少している。

![Lancherter_Order12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511532/c2c2424d-1e60-399c-4f5d-d5909a4fde04.png)

x軍の武器性能が４倍になったことで、y軍の損耗率が上昇している。

## 二次則の数値計算
```python
#ランチェスター2次則の定義
def odeLan2(t2,z2,cx2,cy2):
    dx2 = -cy2*z2[1]
    dy2 = -cx2*z2[0]
    return [dx2,dy2]

x02, y02 = 5, 10
Tend2 = 1 #シミュレーション時間
cx2,cy2 = 1.0, 1.0
sol = solve_ivp(odeLan2, t_span=[0,Tend2], y0=[x02,y02], args=(cx2,cy2),dense_output=True)
tc3 = np.linspace(0,Tend2, 100)
yc3 = sol.sol(tc3)

Tend2 = 1
cx2, cy2 = 4.0,1.0
sol = solve_ivp(odeLan2, t_span=[0,Tend2], y0=[x02,y02], args=(cx2,cy2),dense_output=True)
tc4 = np.linspace(0,Tend2,100)
yc4 = sol.sol(tc4)
```
## 二次則の計算結果
![Lancherter_Order13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511532/0fc203e5-ecf9-0117-31d5-2b84f4fa1386.png)

一次則と同条件で計算している。損耗が非常に早く、0.55秒でx軍の戦力は負になっている。
![Lancherter_Order14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3511532/1cbf308d-4169-9e93-e0a2-56ec478f2c0c.png)

x軍の武器性能が4倍になったことで、y軍の戦力が指数関数的に減少し、1.0秒後も戦力が残存していることがわかる。

# まとめ
ランチェスターの法則を、Pythonを用いて計算し、武器性能と一次則・二次則の違いによる戦力の損耗過程に及ぼす影響が確認できた。

# 参考文献
- Python意思決定の数理入門, 橋本洋志, 牧野浩二, 佐々木智典, オーム社, 2022
【初級者・中級者向け】便利な拡張機能

こんちは　[tetudo-megane](https://scratch.mit.edu/users/TM_sub/)でございます。
今回はscratchをするうえで便利な拡張機能を紹介したいと思います。
そもそも拡張機能って何という方は[こちら](https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%A9%E3%82%A6%E3%82%B6%E6%8B%A1%E5%BC%B5%E6%A9%9F%E8%83%BD)から
# scratch addons
scratchにもまさかの拡張機能があるんです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712471/709f7944-f9b8-7663-00f7-1acb75d1c6cb.png)
ここで違和感を感じた人はすごいですね。scratch歴長いと思います。
上のバーが青色ですね。（普通は紫色）
これがscratch addonsという拡張機能の効果です。

scratch addonsの効果
・上のバーの色を変えられる
・プロジェクトに入れる画像が高画質になる
・ロード時間が短くなる
などなど
いいところたくさんあるんですよ～

実際にscratchやってる人だと入れてる人多いんですよね。
僕も半年くらい前に入れてるんで、ないとめっちゃ不便です。

# scratch addonsの入れ方
まずは[scratch addonsのサイト](https://scratchaddons.com/)にアクセスします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712471/310ecc0f-5d97-da28-70f8-36a26471955a.png)
こんな画面ですね。
こっから他と同じように拡張機能入れましょう。

入れたら…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3712471/bc4047ec-5ce6-86d9-0a28-a1f3e35c8b60.png)
のように右上にマークがあるんでカーソルを持っていくと設定ができます。
ここでのおすすめはいったん重くなるから全部外しておいて、そのあと欲しいのを入れていくという方法です。
そのようにして拡張機能を入れたら設定は完了です！

あとはscratch人生を楽しみましょう。

最後までご覧いただきありがとうございました。
【オープンチャット】「プログラミングサポートスレ」を作りました。

LINE のオープンチャット(「プログラミングサポートスレ」)を開催しています(メインアカウントの存在および本名がバレることはありません)。

https://line.me/ti/g2/-34RvI84WGC4A84i_bbYZ-uGr4yhGptj7Loq-g?utm_source=invitation&utm_medium=link_copy&utm_campaign=default

![QrCode.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/55617c5a-bd0a-820b-a801-f1d563a15d0f.jpeg)

# 「プログラミングサポートスレ」を作りました

30年以上プログラムの開発をしている私が「あらゆるプログラミング言語のサポート」を目的としてオープンチャットを作りました。

* どんな細かい質問でも受け付けます。
* 開発中のプロジェクトの紹介をしていただいてもかまいません。
* 他、思いついたら追記します。

# よろしくお願いします。
Google Places API (New)で言語コードを設定せず沼りかけた

# 結論

- 言語コードを設定する
- 公式ドキュメントをしっかり読む

# 経緯

Next.jsでAPIからGoogle Places API (New)を叩こうとしたら、400番エラーになったので沼りかけた

# 実際にやったこと

curlでAPIを叩いたときの例が掲載されており、`"X-Goog-Api-Key: API_KEY"`のAPI_KEYを正しく設定すれば情報を取得できる。

次の例は、circle によって定義された、半径 500 m 以内のすべてのレストランの表示名に対する Nearby Search（New）リクエストを示しています。

``` bash
curl -X POST -d '{
  "includedTypes": ["restaurant"],
  "maxResultCount": 10,
  "locationRestriction": {
    "circle": {
      "center": {
        "latitude": 37.7937,
        "longitude": -122.3965},
      "radius": 500.0
    }
  }
}' \
-H 'Content-Type: application/json' -H "X-Goog-Api-Key: API_KEY" \
-H "X-Goog-FieldMask: places.displayName" \
https://places.googleapis.com/v1/places:searchNearby
```

実際に同じようなことをやるAPIを作ってみる

``` api/map/route.ts
import { NextResponse } from 'next/server';
import { config } from '@/lib/config';
import { LatLng } from '@/app/types';

export async function POST(req: Request) {
  if (req.method !== 'POST') {
    return NextResponse.json({ error: 'Method Not Allowed' }, { status: 405 });
  }

  try {
    const { lat, lng }: LatLng = await req.json();

    const apiKey = config.GOOGLE_MAPS_API_KEY;
    const apiUrl = 'https://places.googleapis.com/v1/places:searchNearby';
    const response = await fetch(apiUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-Goog-Api-Key': apiKey!,
        'X-Goog-FieldMask': 'places.displayName',
      },
      body: JSON.stringify({
        includedTypes: ['restaurant'],
        maxResultCount: 10,
        languageCode: 'ja',
        locationRestriction: {
          circle: {
            center: { latitude: lat, longitude: lng },
            radius: 500.0,
          },
        },
      }),
    });

    const data = await response.json();

    if (!response.ok) {
      return NextResponse.json(data, { status: response.status });
    }
    return NextResponse.json(data, { status: 200 });
  } catch (error) {
    console.error(error);
    return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 });
  }
}

```

## 400番エラーになる

ログ出力してみるとこう書いてある。
**言語コード「*」が無効です。https://developers.google.com/maps/faq#languagesupport のサポート言語リストを参照してください"**

``` json
{
  error: {
    code: 400,
    message: "Invalid language code '*'. See the list of supported languages at https://developers.google.com/maps/faq#languagesupport",
    status: 'INVALID_ARGUMENT'
  }
}
```

## 公式ドキュメントを見る

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3351724/68c3a919-36ae-7057-50f1-374ef07ccb4d.png)

🤔「いや、省略してもいいって書いてあるやん」

## コードを修正する

API作成時のbodyに言語コードを設定したところ、正しく取得できました。

``` ts
  body: JSON.stringify({
    includedTypes: ['restaurant'],
    maxResultCount: 10,
    languageCode: 'ja',
    locationRestriction: {
      circle: {
        center: { latitude: lat, longitude: lng },
        radius: 500.0,
      },
    },
  }),
```
kotlin + spring boot プラグイン自分メモ

# detekt
linter兼formatter。RubyでいうRubocop的なやつ。
formatterは拡張機能なのでgradle.build.ktsのdependenciesに追記する必要あり。

使いたいコマンド
```.kts
// コードを精査しつつフォーマットしてくれる。
./gradlew detekt --auto-correct
```

##### リンク
**[Gradleのプラグインページ](https://plugins.gradle.org/plugin/io.gitlab.arturbosch.detekt)**
**[参考ページ](https://zenn.dev/msksgm/books/implementing-server-side-kotlin-development/viewer/chapter-03-01-impl-setup#:~:text=rider/database%2Drider-,detekt,-%E3%81%BE%E3%81%9A%E3%81%AF%E3%80%81Kotlin%20%E3%81%AE)**
Ubuntu 22でイヤホンジャックに挿したイヤホンマイクが認識されない

## 状況

- Ubuntu 22でイヤホンジャックに挿したイヤホンマイクが認識されない

## 環境

<table>
<tr>
	<th>OS</th>
	<td>Ubuntu 22.04.4</td>
</tr>
<tr>
	<th>PC</th>
	<td>MacBook Pro 13 inch 2019: 1.4GHz Core i5</td>
</tr>
</table>

## 解決2 (2024年07月16日版)

USBのドッキングステーション（USB Type C Hub）を購入。ケーブルを整理する目的で購入したが、イヤホンジャックがついており、普通のイヤホンマイクも使えるようになった。

### 購入したもの
- [Selore&S-Global 13in1 2つHDMI＋DP](https://www.amazon.co.jp/dp/B0CKSWQZVS)

## 解決1 (2024年02月23日版)

USB接続のイヤホンマイクを購入して接続。イヤホン、マイクともに無事認識された。しかし、イヤホンジャックのつながるPCで使っていたときには、ZoomやSlackで、マイク入力を検知して、上下に動いていたインジケータが反応しなくなった。

### 購入したもの
- [エレコム イヤホンマイク HS-EP19UBK](https://www.amazon.co.jp/dp/B099RMNXK4)

## やったけど解決できなかったこと

- 再起動（要所々々で複数回）
- 「設定」の「サウンド」の「出力」「入力」において、接続したイヤホンマイクの、イヤホンもマイクも認識されていないことを確認した
- `alsamixer` コマンドによる出力の確認。こちらでも出力がないことを確認
- サウンドドライバ（`pulseaudio`）の更新
- `/etc/modprobe.d/`あたりのファイルをこちょこちょ編集
jestでReact Routerを使っているテストでuseNavigate() may be used only in the context of a <Router> componentエラーがでる

# はじめに

React Router v6を使っているテストで困ったのでまとめます

# 問題

以下のテストを実行したところエラーが出ました

```tsx
import { BrowserRouter } from "react-router-dom";
import App from "../App";
import { render, screen } from "@testing-library/react";

describe("title", () => {
  it("should render title", () => {
    render(<App />)
    expect(screen.getByText("デジタル名刺アプリ")).toBeInTheDocument();
  });
});
```

```
jest  useNavigate() may be used only in the context of a <Router> component.
```

# 解決方法

renderのときにBrowserRouterで囲んであげました

```tsx
import { BrowserRouter } from "react-router-dom";
import App from "../App";
import { render, screen } from "@testing-library/react";

describe("title", () => {
  it("should render title", () => {
    render(
      <BrowserRouter>
        <App />
      </BrowserRouter>
    );
    expect(screen.getByText("デジタル名刺アプリ")).toBeInTheDocument();
  });
});
```

# おわりに

久しぶりに書くと忘れるものですね
【BigQuery】縦持ちのデータをカンマ区切り文字列として1セルに集約（STRING_AGG）

# やりたいこと
顧客名`customer`に対して注文商品名`item`が縦持ちされているテーブルを想定します。
各顧客の注文商品名をカンマ区切りで1つのセルに格納したいとします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3341655/c7e40a42-61e0-8e68-38ad-c51025f27649.png)

# 結論
**STRING_AGG関数を使用します。**
文字列とNULLが混ざる場合（例：Eさん）、NULLが無視されます。
NULLだけの場合（例：Fさん）、NULLが返されます。

```sql
WITH
  test_table AS (
  /*
    テスト用テーブルの作成
  */
    SELECT 'Aさん' AS customer, 'コーヒー' AS item
    UNION ALL
    SELECT 'Aさん' AS customer, 'チョコレート' AS item
    UNION ALL
    SELECT 'Bさん' AS customer, '紅茶' AS item
    UNION ALL
    SELECT 'Bさん' AS customer, 'クッキー' AS item
    UNION ALL
    SELECT 'Cさん' AS customer, 'コーヒー' AS item
    UNION ALL
    SELECT 'Dさん' AS customer, 'コーヒー' AS item
    UNION ALL
    SELECT 'Dさん' AS customer, 'チョコレート' AS item
    UNION ALL
    SELECT 'Dさん' AS customer, 'クッキー' AS item
    UNION ALL
    SELECT 'Eさん' AS customer, 'コーヒー' AS item
    UNION ALL
    SELECT 'Eさん' AS customer, NULL AS item
    UNION ALL
    SELECT 'さん' AS customer, NULL AS item
  )

SELECT
  customer
  ,STRING_AGG(item) AS items

FROM
  test_table

GROUP BY
  1

```
[BigQuery公式：STRING_AGG関数](https://cloud.google.com/bigquery/docs/reference/standard-sql/aggregate_functions#string_agg)
Speed Wi-Fi HOME 5G L13 を定期的に再起動する

## やったこと

Speed Wi-Fi HOME 5G L13を定期的に再起動するスクリプトをpythonで作った。

## 概要

Speed Wi-Fi HOME 5G L13 を導入しました。
Wifiは使っていません。たまーにWAN側が不安定になります。
定期的に再起動しようと思いましたが、設定できるのは「週に一度、ランダムに再起動する」でした。
無計画に再起動されては困るので、任意のタイミングで再起動できるようにしました。

## 調べたこと

- ブラウザのDevToolsでどんなリクエストを出しているか調査
- ソースを読んだり、インターネットで類似のコードを探したり(古いコードが多く、ヒントにはなれど役には立たず)

## 処理

### ログイン

1. LDを取得
1. パスワードのSHA256ハッシュを計算
1. そのハッシュ値にLDをくっつけてSHA256ハッシュを計算
1. それがpasswordになる

### 再起動

1. wa_inner_version,cr_version,RDを取得
1. wa_inner_version+cr_versionのSHA256ハッシュを計算
1. そのハッシュ値にRDをくっつけてSHA256ハッシュを計算
1. それがADになる

## ソース

https://github.com/bugcity/reboot_l13

## 実際の運用

10分ごとにWAN側の速度を測定して記録しているので、それを外して毎日3:05に実行するようcronに仕込んでいます。
YAPC:Hiroshima 2024 に参加しました!

# YAPCとは

https://yapcjapan.org/2024hiroshima/

> YAPCはYet Another Perl Conferenceの略で、Perlを軸としたITに関わる全ての人のためのカンファレンスです。 Perlだけにとどまらない技術者たちが、好きな技術の話をし交流するカンファレンスで、技術者であれば誰でも楽しめるお祭りです！

Perlのイベントとは書いてありますが、その他技術やエンジニアとしての考え方などさまざまなセッションが準備されていました。

また今回は学生支援制度というもので参加しました。
これは企業の方々が学生の旅費を支援してくれるというものでした。
私は福岡に住んでいますが、この制度で広島に行くことができました！本当にありがとうございます！！

https://blog.yapcjapan.org/entry/2023/10/10/120000


# 特に気になったセッション

### Go to cloudflare workers
codehexさんによる講演でした。

https://speakerdeck.com/codehex/go-to-cloudflare-workers

- GCPからCloudflareへ移行した話
- Cloudflareへのデプロイは簡単にできる
- Honoを使用した
- Log,Metrics,Traceなどのツールを自作した

などなど面白い話がてんこ盛りでした。
また、HonoやCloudflareにも興味があったためかなり面白かったです。

それに伴いHonoへの興味がかなり出たので、先日あった[ハックツハッカソン](https://cup.hackz.team/)でHonoを使ってみました！！

よければ見てください！

https://topaz.dev/projects/59c5d93aa2214b3184ef


### MyFavorite Protocol Idempotency-Key Header
ohbaryeさんによる講演でした。

https://speakerdeck.com/ohbarye/my-favorite-protocol-idempotency-key-header

- Idempotency Key Headerというプロトコルがあるよ
- POSTやPUTなどのメソッドにおいても冪等性を担保する
- そもそも冪等性の重要性はなんなの
- どうやって実装するの

私もWebのサーバサイドを開発していますが、冪等性を気にしてAPI開発などを行ったことがなかったため非常に貴重なお話でした。
今度自分のAPIにもIKHを取り入れてみたいなと思いました。


### AWS ECS で好きなだけ検証環境
fujiwaraさんによる講演でした。

https://speakerdeck.com/fujiwara3/yapc-hiroshima-2024

[mirage-ecs](https://github.com/acidlemon/mirage-ecs)はECSのタスクの管理とReverse Proxyを行なってくれるOSSだそうです。

利用方法として、Githubのブランチごとに環境を切り分けてテストがしたかったり、非エンジニアの方(例えばデザイナーの方)が特定のブランチでデザインを確認したかったりという場合に重宝しているそうです。

これはかなり使ってみたいと感じました。タスク定義を渡せばいいそうなので、FagateかEC2も選べると思うし、活用次第で面白いことができるなと感じました。

# 懇親会

![IMG_1007.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2086809/67167a9d-16d2-f6a2-ea54-05b21c82985e.jpeg)

![IMG_1008.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2086809/9b1fe6ed-c5eb-61cf-ce19-6038b28d7dee.jpeg)

YAPCの懇親会にも参加しました！！
mirage-ecsの話をされていたfujiwaraさんともお話しさせていただきました！！

# 最後に

こういった大型なカンファレンスにはあまり参加したことがなく結構緊張していたのですが、セッションもとても興味深い話ばかりでしたし、企業の方々からも質問に答えていただいたり、エンジニアとして大切なことなどのありがたいお話をお聞きすることができ本当に充実した時間でした。こういった機会に立ち会えたのもYAPCを運営してくださっている方々をはじめ、YAPCの学生支援として旅費を賄ってくださった企業の方々のおかげなので本当に感謝しかありません。ありがとうございました！！
チームが重視すべきCSSの4つの原則

# 1. はじめに
チームでの開発においては特に、どのようにコードを書くかについて共通の理解を持つことが重要です。
本記事では、CSSの4つの原則に焦点を当て、私と一緒に開発を行っている人たちとまずは「何を重視するか」についてディスカッションを実施したので、備忘録としてここに残します。

＊4原則なので、4つ守れるといいですが、競合するものもあるので、迷ったときの指針を定めました。

# 2. チーム状況
- 対象読者：初学エンジニア〜中堅エンジニア
- 開発環境：大規模開発プロジェクトあり、保守作業も含む

# 3. メンバーが日々意識していること
- **予測しやすさ**
コードは読みやすく、理解しやすいものでなければならない。
- **重複を避ける**
同じスタイルルールを何度も書かず、汎用的なコードにリファクタリングする。
- **CSS変数の使用**
変更が必要になったときの修正箇所を最小限に抑えるために、CSS変数を活用する。
- **固定値の使用を避ける**
レスポンシブデザインを考慮し、可能な限り固定値を避ける。

# 4. ディスカッション内容
### 「予測しやすいコード」
チームメンバーがコードを理解しやすくするための土台。
これがないと、他を意識したとて、わかりづらいコードになる。

### 「再利用しやすい」
大規模開発や保守を考慮すると、「再利用しやすい」コードの重要性が高い。
初めから再利用可能なコンポーネントを設計することで、将来的な修正や機能追加が容易になる。

### 「保守しやすい」
保守の容易さは保守の効率性に直結する。
保守しやすいコードは、長期的なプロジェクトの成功に不可欠ではあるが、上記の「予測しやすい」「再利用しやすい」ができていれば、自ずと「保守しやすい」のではないか。

### 「拡張しやすい」
やりすぎると逆効果になる可能性がある。
必要以上に抽象化や汎用化を進めると、コスト（時間）がかかるので要注意。
しかし、適切なレベルでの拡張性は、将来的な機能追加や変更に対応しやすくはなる。

参考
[【YAGNI原則】必要になると思っているなら、それはいらない](https://plainprogram.com/yagni-principle/)

# 結論
私たちのチームでは、「予測しやすいコード」を基盤とし、「再利用しやすい」CSSの書き方に重点を置くことになりました。
しかし、この原則を守るためにも、チーム全体でのルールを定め、コーディングスタイルを統一する必要があります。
そうすることで、大規模な開発プロジェクトでも効率的にアプリケーションの開発を進めることができるため、今後は、ルールやガイドラインを検討して行きます。
ぼくがつくったさいきょうのおーえすを語ろう#1(導入編)

# このシリーズについて
このシリーズは私がSecHack365(2023年度学習駆動コースの坂井ゼミです)を通して制作した「ぼくがつくったさいきょうのおーえす(Shizuku)」についてただただ語るだけのシリーズです。もし興味があれば[GitHub](https://github.com/danfunc/Shizuku)を覗いてくれると嬉しいです。[SecHack365成果発表会](https://sechack365.nict.go.jp/presentation/)もあるので興味がありましたら3/2アキバスクエアに来てくれると嬉しいです。

# おーえすのロゴ（[SecHack365成果発表会](https://sechack365.nict.go.jp/presentation/)での目印)
![Screenshot 2024-02-16 at 19.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3476367/ed91b1a1-f17f-3538-d668-26bc0d92b6a3.png)
ぼくがつくったおーえす(Shizukuと言います)のロゴです。このマークがポスターに10cmくらいの大きさで貼ってあることでしょう(タイトルにデカデカとぼくがつくったさいきょうのおーえすと書いてはあるのですがQiitaのアイコンがないので念のため...)

# 構成
1. ぼくがつくったきっかけ
2. さいきょうとは何か
3. OSとは何か
---↑この記事はここまで---
4. つくったおーえす
5. オブジェクトとオブジェクトシステム

# ぼくがつくったきっかけ
僕は既存のOSに対して欠点や不満を大量に抱えています(だから自作OSをやっています)
この不満には色々ありますが最大の不満は「OS内部構造や設計思想を一つの概念で言い表せない」ということです。たとえば有名なUNIX哲学の一つに「全てはファイルである」というものがあります。素晴らしいことに最近のLinuxではアプリケーションから全てはファイルであるかのように見えてるのではないのかなと思います。しかし、Linuxカーネル用のドライバ開発など、カーネルからはでは、必ずしも全てはファイルとして見えているとは限りません(LinuxではI2Cデバイスドライバを開発する際、i2c_register_driver関数などの関数を呼び出す必要があります。間違ってたらごめんなさい。追記:(この記事を書きながらなぜこのような仕組みになっているのか考えていたら)Linuxカーネルモジュールは読み込まれる時に動的リンクがどうせ行われるみたいだから速度優先で不要と判断されたのかorz)。このことから、僕はLinuxが複雑でそう簡単に理解や開発を行えるカーネルではないと思っています。そこで僕はカーネル空間やユーザー空間も内部の構造をたった一つの概念で言い表すことができるカーネルを作ることを決意しました。

# さいきょうとは
- 簡単に使いこなせる
- 簡単に動作がわかる
- 簡単に開発ができる

ことだと思います(盛大にタイトル詐欺してます。わかりやすさがさいきょうということで許してくださいなんでもしますから)。これを外から見ても中から見ても満たすためにはまずOSとは何か、OSに求められるものはなんなのかを整理することから始めました。

# OSとは何か
大きく分けてOSの役割は4つあります
- デバイス操作
- デバイスの抽象化
- プログラム間の通信
- リソース管理

詳しく説明していきます

## デバイス操作
これはデバイスドライバというカーネルになんらかの方法で組み込まれたプログラムが行います。デバイスドライバの性質は次のようなものがあります。
- 一つのデバイスドライバと、一つのデバイスは対応しています(複数のデバイスドライバが一つのデバイスを操作することはありません。逆に同じ種類のデバイスでプログラムの使い回しが可能な場合など複数のデバイスを一つのドライバで操作することはあります)
- デバイスドライバにはデバイスを操作する権限をカーネルから与えられます(これはマイクロカーネルやLinuxなど拡張可能なカーネルの場合です。もちろんカーネルに直接リンクで組み込まれたものもあって、それは完全にカーネルの一部なので当たり前にデバイスを操作できます)
- デバイスドライバはデバイスの動作に専念すべきです(全てがそうかどうかはわからないのでここではすべきとしています)

## デバイスの抽象化
デバイスの抽象化とはアプリケーションが大雑把にディスプレイとかスピーカーとかMetalとかVulkanとかOpenGLとかDirectXとかとかとかとにかく抽象的なデバイスへの操作を、具体的なデバイス(例えばRTX3080とか)への操作へと変換することです。最近は抽象的デバイスを操作すると、複数の具体的デバイス(複数のGPUやスピーカーが搭載されている状況)から、特定の具体的デバイスだけを操作させる仕組みも担っています。複数のスピーカーからOSの機能で特定のスピーカーを選ぶ(あるいはスピーカーを変える)とそのままそこから音が出るという仕組みも、抽象化の仕組みの中に備わっています。

## プログラム間の通信
Linuxではプロセス間通信と呼ばれているものです。Linuxではプロセス間通信の手段はいくつかあります(興味があれば共有メモリとかパイプとかで調べると幸せになれます)
プロセス間通信を行う目的として、マルチスレッドプログラミングや、サーバークライアントモデルを実現することが挙げられます。Linuxではプロセス間通信の手段として共有メモリ、シグナル、ソケット等があります。
カーネルは上のような仕組みを提供すると同時に、通信しているプログラムを確かめる(送信元の特定と送信先の保証)仕組みと、通信の秘匿性を保証する仕組み(これが外部のコンピューターと通信するなど秘匿性を担保できない場合、代わりに暗号化機構を使用して秘匿性の担保)を提供する必要があります。

## リソース管理
一口にリソース管理と言ってもリソースの中には計算能力や記憶力、デバイスまで含まれる場合もあって複雑ですがここではそれを占有するプログラムは一つであるべきものとします。例えばデバイスを占有するのは一つのデバイスドライバであるべきです(そしてアプリは抽象デバイスおよびデバイスドライバ経由で操作するべきです)。これに加えてCPUの処理時間の一部やメモリ空間の一部を一つのプログラムが占有できるように管理してあげることがOSに求められています。管理とはリソースをそのプログラムが占有する権限を持っているか確認して、そのリソースが他のプログラムによってすでに占有されていないか確認するなどを行うことです。LinuxではこれはVFSやプロセス管理(CPU時間はnice値によって割り当てられるそうですｱﾝﾏｸﾜｼｸｼﾗﾝｹﾄﾞ)が担います。

# 続く
ぼくがつくったさいきょうのおーえす(Shizuku)の紹介は[SecHack365成果発表会](https://sechack365.nict.go.jp/presentation/)で行おうと思います(終わったらQiitaにも解説記事を投稿します)のでもし僕はどうやってこれらを実現したかに興味を持っていただけたらぜひ来てください！！！
【オープンチャット】「Emacs Lisp を極めるスレ」を作りました。


LINE のオープンチャット(「Emacs Lisp を極めるスレ」)を開催しています(メインアカウントの存在および本名がバレることはありません)。

https://line.me/ti/g2/wFxJwGl1kllZujisGZshR4zTrZyC0SienifITw?utm_source=invitation&utm_medium=link_copy&utm_campaign=default

![QrCode.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140610/cc55f6fd-b352-0f57-defe-6d443cd17c77.jpeg)

# 「Emacs Lisp を極めるスレ」を作りました

30年以上 Emacs Lisp の開発をしている私が「Emacs Lisp 開発のサポート」を目的としてオープンチャットを作りました。

* どんな細かい質問でも受け付けます。
* .emacs (.emacs.d/init.el) の設定方法などもサポートします。
* Emacs Lisp で開発中のプロジェクトの紹介をしていただいてもかまいません。
* 他、思いついたら追記します。

# よろしくお願いします。
mac+vscodeで範囲指定したい

# mac＋vscodeで範囲指定するには

## 問題点

特に何も考えずにMACにscodeをインストールし、awesome-emacs-keymapという拡張機能を載せて、ctrl-space(c-space/^space/C-SPC)をしても範囲指定(set-mark-command)が始まりません。
emacsなどではこれで範囲指定が始まります。これができないと、マウスに手を伸ばすとか、Shiftキーを押しっぱなしにする必要が出てきます。Shiftキーの場合にはカーソルキーを使わないといけませんよね。つまりどちらの選択肢でも手がホームポジションから離れてしまう。これものすごく不便なわけです。

## やったこと

### 入力ソースのショートカット変更

C-spaceで入力ソースが切り替わる画面がポップアップしてきます。
そこで色々調べてみると、
[VSCode でもEmacsのマーク機能を使いたい](https://note.com/sho7650/n/n5bec809809e9)という記事を見つけました。

なるほど。ここにはc-@で動くということが書いてあります。やってみましたが、うまく動きません。もしかしてawesome-emacs-keymapが動いていないのか、とか思ってしまいます。awesome-emacs-keymapでキーバインドを調べてみると、たしかにc-spaceとかｃ-s-2と書いてあって、英語版のキーボードだと２のシフトで＠マークだということを考えると問題なさそう。でも私は日本語キーボードを使っています。これが原因かも。いや、そもそもvscodeでc-@を打つとターミナルモードが起動しますので、他の拡張機能がc-@を奪っている可能性もあります。
いろいろと拡張機能を入れちゃったので、どれが原因かわからず。涙

またググってみていると、macの設定の中のキーボードからショートカットにいき、入力ソースを選択すると、前の入力ソースを選択とか入力メニューの次のソースを選択などのショートカットの設定が見えて、この機能にc-spaceが割り当てられていることがわかりました。

これを外すと確かにc-spaceを押下しても「入力ソースの選択」は出なくなりました。しかしvscode上での範囲の選択開始になりません。

### emacsでやる？

半分諦めてemacsで入力をするかなぁなどと考え、調べてみたら、emacs mac portが良さげ。早速インストールを開始。３０年くらい前にSun Microsystemsのワークステーションで使っていたemacsを久しぶりに使うか、とインストール後にtutorialをちょこちょこやって記憶を取り戻します。

おお、確かにBufferを切り替えながら色々やったなぁ。もう覚えていないけど。c-x 1など忘れていましたので、大変でした。とはいえざっと思い出せていい感じかな。

### spotlightの設定変更

emacsの世界に行ってしまうか、と思い始めていましたが、ちょっと待てと、改めてググってみていたら[C(Control)-スペースで Spotlight が起動されてしまう](https://www.pistolfly.com/weblog/2008/01/ccontrol-spotlight.html)というページにSpotlightが邪魔をしているというのも見つけました。そこでmacの設定のSportlightの設定を選びます。そうするとキーボードショートカットのところにc-spaceがありました。

これを変更して再度vscodeを動かしてみましたが、やっぱりダメ。vscodeでc~spaceを押下しても、範囲指定の開始になりません。

### 再起動でやっと動く

もしかして、と気がつき、vscodeの再立ち上げをしてみました。でもだめ。こうなったらmacの再起動もしてみました。

おお、そうしたら、やっとvscodeの範囲指定がc-spaceでできました。

macのどこをいじると再起動しなければならないのかよくわかっていませんが、これで今はうまくいきました。

## おわりに

mac初心者で、windowsから引っ越してきたばかりであるため、macの設定などについてよくわかっていません。そのため、適当にいじったらうまくいったというレベルで恐縮です。

もしかしたら他にもハマっている人がいるかもしれないので、メモを残しておきます。というのは私がググった限りでは入力ソースとspotlightの両方に引っかかっている可能性が書いてある情報が見つからなかったためです。ま、よく探せばあるのかもしれませんが。

注：あとで再度探してみたら、[Emacs 超クイックリファレンス](https://www.cc.kyoto-su.ac.jp/~mmina/bp1/EmacsSuperQuickReference.html)の「4.カット／コピー／削除」の所にc-spaceが「古いOSXではSpotlight検索、新しいOSXでは日本語入力モード」に割り当てられているという記述がありました。やっぱりよく探せばあったのか。でも自分のMACだと両方に引っかかったけど。

以上
【kintone】1件のレコードの取得と値の更新-kintone Rest API(初心者/入門)

# 初めに
[前回](https://qiita.com/pomo/items/9fcb8e1a9fb26a1bd7f5 "JavaScriptAPIを使ったレコード取得と更新")はJavaScriptAPIを使っての値の取得と更新を試しました。
今回はRESTAPIで`1件のレコードの取得と値の更新`サンプルです。
※複数件はまた別です。


# 手順
1. フィールドコード`テキスト`という文字列を1つ設置してください
1. 下記コードをコピペしてtest.js等適当な名前で保存し、アプリ設定でアップロード
1. レコードを追加し、適当な文字を入れて保存
1. レコード詳細画面で押下して値の更新。今回ABCという文字が入力され画面が更新されます。



```test.js
(() => {
  'use strict';
  const fieldCode = "テキスト"
  
  // ボタン押下時に書きかえる
  const updateFunction = async () =>{
    const appId = kintone.app.getId();
    const recordId = 1;
    
    const body = {
      app:appId,
      id: recordId
    };
    const res = await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', body);
    const record = res.record;
    //取得したデータの表示
    alert(`書きかえ前の${fieldCode}の値は${record[fieldCode].value}だよ`);
    
    
    // 更新のパラメータを宣言
    const putBody = {
                app: appId,
                id: recordId,
                record: {
                  [fieldCode]: {
                    value: 'ABC'
                  }
                }
              };

    // 非同期で更新
    await kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', putBody);
    // 画面の更新
    location.reload();
  }
  
  kintone.events.on('app.record.detail.show', (event) => {

    // ボタンの設置と作成
    const button = document.createElement("button")
    button.innerText = "書き換え"
    button.addEventListener("click",updateFunction)
    
    // kintoneに表示する要素（位置）を取得して、ボタンを設置。
    const el = kintone.app.record.getHeaderMenuSpaceElement()
    el.appendChild(button)

  // 必ずeventを返してあげる
  return event
    
  });
  
})();
```

<details><summary>書き換えの様子</summary>

### 書き換え前
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719638/98686bd5-85a3-ca10-b281-574d1f75f09f.png)
### 書き換え後
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3719638/575880f7-c595-874d-97c1-1631aa7fe053.png)

</details>


### 説明
今回はレコード詳細画面にて、レコード番号が1のレコードを取得し、レコード番号1に対して更新を行ってます。適宜変更してください。


:::note info
- 取得 => `await kintone.api(kintone.api.url('/k/v1/record.json', true), 'GET', body)`
ではRESTAPIを使ってレコードを取得してます。ですが、詳細画面であればAPI数も使いもったいないので-`kintone.app.record.get()`で取得してあげた本来は良いです。サンプルという事で。使う場面は、別アプリのデータ取得する場合が多いのかなと思います。
- 更新 => `await kintone.api(kintone.api.url('/k/v1/record.json', true), 'PUT', putBody);`で値を更新し、更新した後の値を確認するために`location.reload()`で画面をリロードし直してあげてます。
:::

### async/await??
突然asyncとawaitという文字がついています。`const updateFunction = async () =>{...}`や`await kintone.api(...)`の部分です。
`ざっくりですが、こいつを使うことで返答があるまでお前らちょっと待ってくれや`という状態になります。

非同期処理してくれるRESTAPIでデータ取得した際、通常この結果を待たずに上から下に処理が進みます。待たずに進むと期待していたrecordも取得できないまま処理が進み、値を表示しようとしてもに空の段階のものが表示されます。なので同期的に処理してねという合図としてasync/awaitを使用しています。私も最初全然わかりませんでした:relaxed:(今尚不安)

こちらも詳しくは下記にリンク張ります。言葉足らずですみません、セツメイムズカシイ。

https://cybozu.dev/ja/kintone/tips/development/customize/development-know-how/javascript-customize-middle-async-await/


REST APIについて、下記ドキュメントに詳しくわかりやすく記載されてます。

https://cybozu.dev/ja/kintone/docs/rest-api/records/

# おわりに
今回は`1件のレコード`をRESTAPIで取得して更新してみました。
複数になるとbodyにrecordIdではなくqueryを使用していくようになるので、そちらもまた別に書いていきたいと思います。

### 楽しいkintoneライフを:blush:
PowerShellの起動方法いろいろ

PowerShellは起動方法が何パターンかあるのでそれのメモです。(OSはWindows)
タスクバーやスタートメニューにピン止め以外にも色々あり「こんな起動方法もあるのか」、というのもあるかもしれないので何か役に立てば幸いです。

# 1. 「Windowsキー + S」で検索ボックスから起動
"PowerShell"と打ちPowerShellを選択すれば起動できます。
PowerShell ISEもこれで起動できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/9d87ccf1-24b7-4e00-84fa-91c2d76f2f9c.png)


# 2. 「Windowsキー + R」で「ファイル名を指定して実行」から起動
"pow"くらいまで打つと候補にPowerShellが出てくるのでそれ選択すれば起動できます。PowerShell ISEも可。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/4104723f-ada0-7015-e0ff-02082d7012dc.png)

# 3. エクスプローラーのアドレスバーから起動
エクスプローラ起動時に"Alt + D"でアドレスバーが選択できるのでそこにPowerShellと打てば起動できます。これで起動する場合、カレントディレクトリがPowerShellを開いたパスになるのが地味に便利。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3343332/71c0b4be-ef6f-4fcd-4b93-ae9969a1a062.png)
モチベーション記録①20240222

こんにちは。意識高い系になりたいエンジニアです:eyes:

モチベーション維持の為に、定期的に学習の記録を付けていこうと思います。

:v:まずは現在の状況はこんな感じ
　⚪︎フロントエンド
　　HTML.CSS→中級者くらい、模写やコーディング経験あり
　　JS.React→勉強始めて1週間
　⚪︎バックエンド
　　rails→5ヶ月くらいダラダラ勉強中
　⚪︎インフラ
　　AWS→業務経験6ヶ月程(初級者です笑)

:v:目標:一旦、短期的に4月末にします笑
　⚪︎フロントエンド
　　JS→3月でJSの知識一通り学ぶ。
　　React→3.4月で知識の定着。
　⚪︎バックエンド
　　rails→某サイトの目標チャプターまで。

4月末目標でReactとrailsの知識の定着。
5月からインフラ領域なども勉強しつつ、ポートフォリオ的な部分の作成に取り掛かる予定です。

5-9月くらいで１つアプリを作れたらいいなと。
想定では、大まかにReact,rails,AWSを利用しつつ。。。


:stopwatch:平日2時間(1日休み)+土日4時間=16時間
　こんくらいを目安に暫く頑張ります。

駆け出しエンジニアの方は一緒に頑張りましょう:crossed_flags:
MacでPDFをコマンドラインで処理する

＃MacでPDFを加工する必要があったので調べたことをメモ

## 必要なもの

poppler
ImageMagick

popplerでPDFから画像ファイル切り出し、imagemagickで画像を加工した後、改めてPDFに結合する

## インストール

```bash
brew install poppler  
brew install imagemagick  
```
参考にしたサイト
https://eng.shibuya24.info/entry/pdf2jpg

## PDFから画像ファイル切り出し(poppler)

```
pdfimages -j 002.pdf test002
pdfimages -png 002.pdf test002
```

-jでjpeg出力、-pngでpng出力
実行するとtest002-000.jpg,test002-001.jpg,test002-002.jpg...と、ファイルが出力される。

## 画像の加工(imagemagick)

```
＃サイズを半分にしてjpegに変換
convert -geometry 50% test002-000.png test002-000.jpg

＃一度に処理する
for fname in test002*.png; do
> convert -geometry 50% $fname ${fname%.png}.jpg;
> done
```

## 画像をPDFに(imagemagick)

```
convert *.jpg 2022.pdf
```


## 他のツール（今回は使わなかった）
PDFtk
新しいMacOSだとJava版でないとインストールできないらしい

```
brew install pdftk-java
```
参考にしたサイト
https://note.com/hitoshiarakawa/n/n20c8bc3469f3
PukiWikiのファイル名のデコード

# PukiWikiのファイル名のデコード
## 1. はじめに
PukiWiki は今でも価値あるツールです。簡単な記法である Wiki のページを作れば書式が自動的に整えられるので、書式の整ったページをプログラムで簡単に自動的に大量に作れます。簡単なユーザー制限を設定できるのも便利です。
しかし、メンテナンスの面では、やや苦労します。ページごとのファイル名は、エンコードされているのでどのファイルがどのページに対応するのかわかりにくいです。以前は、pwls という便利なツールが提供されていたが、今、Google で検索しても出てきません。また、文字コードもEUC-JPにしか対応していません。
だったら作りましょう！（と偉そうに書いているが、ChatGPT に助けてもらって作ります。)
## 2. スクリプト
### 2-1. 使い方
Linux で使っていることを想定してます。ls コマンドの出力をパイプラインで渡せば、そのままデコードしてくれるようにしました。これで、いろいろなオプションなどは、ls などのコマンドに任せて、プレーンなフィルターとして機能します。
```bash
ls -ltr | cat -n | pwdecode.py
```
* pwdecode.py が今回のスクリプト
* cat -n を入れるのは、ls -ltr | cat -n と比較して、ファイル名を対応付けやすくするため
### 2-2. 実行例
#### 普通の ls
```bash:普通のls
ls -lt *.txt | cat -n
```
```bash:出力結果
...
150	-rw-rw-r-- 1 www-data www-data   221 11月 29  2023 57696B69456E67696E6573.txt
151	-rw-rw-r-- 1 www-data www-data   206 11月 29  2023 57696B694E616D65.txt
```
#### pwdecode.py を通したもの
```bash:pwdecode.py を通す
ls -lt *.txt | cat -n | pwdecode.py
```
```bash:出力結果
...
150	-rw-rw-r-- 1 www-data www-data   221 11月 29  2023 WikiEngines.txt
151	-rw-rw-r-- 1 www-data www-data   206 11月 29  2023 WikiName.txt
...
```
### 2-3. スクリプト
```python:pwdecode.py
#!/usr/bin/python3
###################################################
# pwdecode.py :
#      Ver.0 2024-02-23
# ■ 概要
#     PukiWiki の wiki/ 以下のファイル名はエンコードされている。
#     これを読めるようにする。実用上は、ls を使うはずなので、
#     ls に対してパイプラインで実行することを想定している。
# ■ 使用例
#     ls -ltr | cat -n | pwdecode.py
#     ※ cat -n を入れておくと、実際のファイル名と簡単に対応付けられる。
###################################################
import sys
import re

# PukiWikiは、utf-8 と euc_jp とがある。成功した方を採用。
def try_decode(encoded_bytes):
    try:
        return encoded_bytes.decode('euc_jp')
    except UnicodeDecodeError:
        pass  

    try:
        return encoded_bytes.decode('utf-8')
    except UnicodeDecodeError:
        return None

# 各行のデコード
def decode_pukiwiki_filename(encoded_strings):
    decoded_filename = ''
    hex_pattern = re.compile(r'([0-9A-F]{4,})(?=\.txt$)') # エンコードされたファイル名部分を抽出
    pos = 0

    for match in hex_pattern.finditer(encoded_strings):
        start, end = match.span()
        decoded_filename += encoded_strings[pos:start]  # 16進数でない部分を追加
        
        hex_str = match.group(1)
        decoded_bytes = bytes.fromhex(hex_str)
        decoded_part = try_decode(decoded_bytes)
        if decoded_part is not None:
            decoded_filename += decoded_part
        else:
            decoded_filename += hex_str  # デコードに失敗した場合は元の16進数の文字列を追加
        pos = end

    decoded_filename += encoded_strings[pos:]  # 残りの部分を追加

    return decoded_filename

# 標準入力を受け取り、エンコードされた部分だけをデコード。
for line in sys.stdin:
    line = line.strip()
    decoded_filename = decode_pukiwiki_filename(line)
    print(decoded_filename)
```
## 3. コメント
* PukiWikiは、EUC-JP と UTF-8 と２種類あります。どちらのエンコーディングもサポートしています。
* 実行環境の差異も Python が吸収してくれるので、LANGが何であっても実行できます。EUC-JPの環境でも、UTF-8の環境でも、正しくデコードされたファイル名を閲覧できます。
* このプログラムは、wiki/ 以下の、.txt で終わるファイル名だけを対象としています。他のディレクトリのファイルを対象にする場合も拡張するには、正規表現をより複雑にする必要がありますね。
【kintone】レコードの取得と値の更新-kintone JavaScript API(初心者/入門)

# 初めに
イベントが始まったらレコードを取得して、値を書き換える。
また、任意のタイミングで値を書き換えたい場面ありますよね。
`その扱いの違い`のサンプルを提示していきたいと思います。

今回はkintone JavaScript APIを使用します。より詳細が知りたい方は下記公式ドキュメントにてご確認ください。大変わかりやすく書かれています。

https://cybozu.dev/ja/kintone/docs/js-api/

# 対象
:::note info
eventとkintone.app.record.get()で取得したレコードの使い分けが分からないとお困りの方
:::


# 手順
1.アプリにフィールドコード`テキスト`という文字列を設置してください。(項目名でなくフィールドコード)

2.下記コードをコピペしてコードエディタ等に張り付け、hello.jsなどのファイル名で保存してください。
3.アプリ設定から設定→JavaScript / CSSでカスタマイズに行き、hello.jsをアップロードして保存:writing_hand:
4. アプリを更新:v:
5.レコードの編集を開く。:thermometer_face:
6.開いたタイミングでテキストが書き換えられます。ボタンを押下するとそのタイミングでのテキスト更新が入ります。

## 説明
ルールは2つあり

:::note info 
- イベントが始まって終わる間に値を更新したい場合は`event.record`で値を書き換え、`return event`で返してあげる
- 任意のタイミングで値を取得して更新したい場合は、`kintone.app.record.get()`で取得して`kintone.app.record.set()`で値を更新してあげる
:::

イベント内での更新について、今回のサンプルは編集イベントです作成しましたが、保存前イベントで値を書き換えて保存するときによく使っています。例えばユーザーが指定の値を入れなかった時に警告をだしてあげるなど。
また、`kintone.app.record.get()`、`kintone.app.record.set()`はボタン押した時に取得・更新したい:cold_sweat:という時に使います

## コード

```hello.js
(() => {
  'use strict';
  const fieldCode = "テキスト"
  
  // ボタン押下時に書きかえる
  const updateFunction = () =>{
    // ボタン押下時の現在のレコードを取得
    const res = kintone.app.record.get()
    // 扱いやすいようにrecordを宣言
    const record = res.record
    
    record[fieldCode].value = "ボタンのテキスト"
    // 更新したrecordを更新。この時最初に取得したresを引数に渡す
    kintone.app.record.set(res)
  }

  // 編集画面を開いた時に動くサンプルにします。editです。
  kintone.events.on('app.record.edit.show', (event) => {
    // イベントで扱えるレコード
    const record = event.record;
    
    alert("編集のイベント")
    record[fieldCode].value = "イベントで書き換えたテキスト"
    
    // ボタンの設置と作成
    const button = document.createElement("button")
    button.innerText = "書き換え"
    button.addEventListener("click",updateFunction)
    
    // kintoneに表示する要素（位置）を取得して、ボタンを設置。
    const el = kintone.app.record.getHeaderMenuSpaceElement()
    el.appendChild(button)

  // 必ずeventを返してあげる
  return event
    
  });
  
})();
```

## おわりに
JavaScript Apiを使った値の取得と更新についてのサンプルでした。

ちなみに、値の更新はJavaScriptApiでは`追加、編集、保存前`等に使用できます。
もし`詳細や一覧`画面で外側から値を更新したい場合はRestApiを使って更新してください。
他のアプリから値を持ってきたい場合も同様です。

https://cybozu.dev/ja/kintone/docs/rest-api/

### 楽しいkintoneライフを:blush:
Ubuntu 22.04にNode.jsとNPMをインストール・アンインストールする方法

Ubuntu 22.04 LTSは、最新の技術と長期的なサポートを提供することで知られています。この記事では、Ubuntu 22.04にNode.jsとNPMをインストールし、後にそれらをアンインストールする方法をステップバイステップで説明します。

# Node.jsとは？

Node.jsは、サーバーサイドでのJavaScript実行環境を提供するオープンソースプラットフォームです。非同期イベント駆動型のアーキテクチャを採用しており、軽量かつ効率的なアプリケーションの開発が可能です。NPM（Node Package Manager）は、Node.jsのパッケージ管理ツールであり、世界最大のソフトウェアレジストリです。

# Node.jsとNPMのインストール

Ubuntu 22.04にNode.jsとNPMをインストールするプロセスは簡単で、以下の手順で完了します。

## ステップ 1: Node.jsのセットアップスクリプトを実行

Node.js v18をインストールするための準備として、以下のコマンドをターミナルに入力します。

```bash
curl -fsSL https://deb.nodesource.com/setup_18.x | sudo -E bash -
```

## ステップ 2: Node.jsとNPMをインストール

セットアップスクリプトの実行後、以下のコマンドでNode.jsとNPMをインストールします。

```bash
sudo apt-get install -y nodejs
```

これで、Node.jsとNPMがUbuntu 22.04にインストールされました。

# Node.jsとNPMのアンインストール

プロジェクトの要件が変わり、Node.jsやNPMをアンインストールする必要が出てきた場合、以下の方法で簡単に行えます。

## Ubuntu リポジトリからアンインストール

Node.jsとNPMをシステムから完全に削除するには、以下のコマンドを実行します。

```bash
sudo apt purge --autoremove nodejs npm
```

## ソースディレクトリからアンインストール

Node.jsとNPMがどこにインストールされているかを確認するには、以下のコマンドを使用します。

```bash
which node
which npm
```

そして、以下のコマンドでそれらを削除します。

```bash
sudo rm -rf /usr/bin/node /usr/bin/npm
```

## アンインストールの確認

Node.jsとNPMが正常にアンインストールされたかを確認するには、以下のコマンドを実行します。

```bash
node -v
npm -v
```

これらのコマンドがエラーを返す場合、Node.jsとNPMは正常にアンインストールされています。

# まとめ

Ubuntu 22.04にNode.jsとNPMをインストールするプロセスは非常に簡単で、開発環境を素早く構築できます。また、プロジェクトの要件に応じて、これらをアンインストールすることも同様に簡単です。このガイドが、あなたの開発作業に役立つことを願っています。
【C#】日付記法 　2024/01/01 or 2024/1/1

## 日付の指定

日付を伴うプログラムを作るときに10月から12月と違い、
1月から9月は2パターンの表現方法がありますよね。

- 01月とか、09月とか
- 1月とか、9月とか

どう指定すればいいか最初分からなかったので、メモしておきます。

下記について、10月から12月はどちらも同じです。


## 2024/01/01　のような表現

1月から9月：01〜09月と表現
1日から9日：01〜09日と表現
<br>
上記のように2桁にしたい場合、

- 月：MM
- 日：dd

と指定するようです。

``` sample.cs
using System;

//class省略

DateTime date = new DateTime(2024,1,1);
Console.WriteLine(date.ToString("MM"));
Console.WriteLine(date.ToString("dd"));
```

```:出力
01
01
```

## 2024/1/1　のような表現

1月から9月：1〜9月と表現
1日から9日：1〜9日と表現


<br>
上記のように桁数を固定しない場合、

- 月：%M
- 日：%d

と指定するようです。


``` sample.cs
using System;

//class省略

DateTime date = new DateTime(2024,1,1);
Console.WriteLine(date.ToString("%M"));
Console.WriteLine(date.ToString("%d"));
```

```:出力
1
1
```


## どっちがお好き？
個人的には、2024/1/1が好きです。
ですが、2024/01/01の表記と違って、1月～9月までは1桁、10月から12月は2桁となるので、桁の分岐などで表示の設定が面倒になるかもしれません。