OmniAICreator/Qiita-1.07M huggingface dataset:
【Flutter】image_picker 簡単導入ガイド

# はじめに
本記事では、Flutterアプリにカメラによる写真撮影機能を導入しましたので、その導入ガイド記事となります。


# image_picker 選定背景
Flutterでは、カメラ機能を実現するためのパッケージはいくつかあります。例えば、image_picker以外ですと、camera、photo_manager などです。
そこで、私が image_picker を選択した背景は、以下のようなことを検討した結果です。

まず、camera パッケージはめちゃくちゃ強力で、カメラの細かい制御が可能なようですが、設定がちょっと複雑になってきそうです。初心者には少しハードルが高いかもしれないと考えました。
一方で、photo_manager は、大量の画像や動画を扱うときに便利なようですが、シンプルなケースではオーバースペック感がありそうでした。

本命の image_picker は、Flutterアプリに写真の撮影やギャラリーからの選択を簡単に追加できそうでした。セットアップも簡単で、必要な機能をすぐに使える点に大きな魅力を感じました。さらに、image_picker はメンテナンスがしっかりしていて、Flutterのバージョンアップにも迅速に対応していそうでした。やはりメンテナンス性は、ストア公開するアプリにとっては非常に重要ですね。

このように、使いやすさ、柔軟性、安定性のバランスがとれてるため、image_picker を選択しました。


# 環境情報
参考までに、導入時の開発環境とバージョンは以下のとおりです。
・MacBook Pro M1(Ventura 13.6.3)
・Android Studio Giraffe | 2022.3.1 Patch 1
・Xcode:15.1

・Flutter:3.13.1
・image_picker:1.0.4


# 導入ステップ
パッケージへのリンクは以下となります。最新情報はこちらをご確認ください。

https://pub.dev/packages/image_picker

### パッケージの追加
まずはパッケージをプロジェクトに追加します。
```zsh
flutter pub add image_picker
```

### AndroidとiOSの設定
AndroidとiOSで、カメラやギャラリーを使うための許可設定をします。

Android : AndroidManifest.xmlに以下を追加します。
```xml
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
```

iOS : Info.plist に、カメラとフォトライブラリへのアクセス理由を追加します。
```xml
<key>NSCameraUsageDescription</key>
<string>カメラを使用する理由を記述</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>フォトライブラリを使用する理由を記述</string>
```
※　iOSアプリを AppStore に公開する場合、上記の説明では審査でリジェクトされる可能性があります。具体的な使用理由を記載するようにしましょう。

### コードの実装
カメラやギャラリーからの写真選択を実装するには、まずは、image_picker パッケージを使えるように、import文を追加します。

```dart
import 'package:flutter/material.dart';
import 'package:image_picker/image_picker.dart';
```

次に、写真を撮影するためのコードと、ギャラリーから写真を選択するためのコードを記述します。
写真を撮影するコード:
```dart
final ImagePicker _picker = ImagePicker();
// カメラを起動して写真を撮影
final XFile? photo = await _picker.pickImage(source: ImageSource.camera);
// ファイルを扱う処理は省略・・・
```

ギャラリーから選択するコード:
```dart
final ImagePicker _picker = ImagePicker();
// ギャラリーから写真を選択
final XFile? image = await _picker.pickImage(source: ImageSource.gallery);
// ファイルを扱う処理は省略・・・
```

これらのコードを使えば、ユーザーがアプリで簡単に写真を撮ったり、ギャラリーから写真を選んだりできるようになり、非常に便利になること間違いなしですね。

なお、写真を撮影するのか、ギャラリーから選択するかの判定する処理については、アプリの要件に関わる部分のため、今回省略しました。ボタンによってどちらかから選択するのか、切り替える処理にするのが簡単な方法でしょう。


# 所感
image_picker により簡単にカメラ撮影、とギャラリー選択機能を導入することができました。本記事では省略しましたが、実際には、撮影後の画像をアプリの中でどのように扱うのか（圧縮するの？DBに保存するの？など）、事前に要件として明確にしておく必要があると感じました。導入だけなら非常に簡単ですので、一度試していただくことをお勧めします。

以上。
yarn installの待機時間を延ばしてビルドを成功させるまで

# 初めに

Next.jsの環境構築をDockerで行いました。以下の手順で進めていて、```docker compose build``` を実行したときにエラーが起きたのでメモを残しておきます。

```
git clone
docker compose build
```

# 問題

Dockerビルドのプロセスで ```yarn install``` を実行しようとしたときに問題が起きました。

```terminal
ERROR [front 5/5] RUN  yarn install 

 > [front 5/5] RUN  yarn install:                                                            
2.015 yarn install v1.22.19                                                                  
2.299 [1/4] Resolving packages...                                                            
2.807 [2/4] Fetching packages...                                                             
67.47 info There appears to be trouble with your network connection. Retrying...
92.78 info There appears to be trouble with your network connection. Retrying...
105.9 info There appears to be trouble with your network connection. Retrying...
126.2 info There appears to be trouble with your network connection. Retrying...
139.0 info There appears to be trouble with your network connection. Retrying...
159.3 info There appears to be trouble with your network connection. Retrying...
172.6 info There appears to be trouble with your network connection. Retrying...
192.8 info There appears to be trouble with your network connection. Retrying...
213.3 info If you think this is a bug, please open a bug report with the information provided in "/opt/app/yarn-error.log".
213.3 info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.
213.3 error An unexpected error occurred: "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.11.tgz: ESOCKETTIMEDOUT"
222.5 info There appears to be trouble with your network connection. Retrying...
```

# 原因

ネットワーク接続に問題があり、何度もアクセスを試みていました。着目していただきたいのが、以下エラーの内容です。```@mui/icons-material/-/icons-material-5.14.11.tgz```というパッケージのダウンロード時に<font color="red">**ESOCKETTIMEDOUT（ソケットタイムアウト）**</font>エラーが発生しています。これがインストール失敗の原因であることが分かります。
```
error An unexpected error occurred: 
"https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.11.tgz: ESOCKETTIMEDOUT"
```

# 解決方法

```.yarnrc``` ファイルをプロジェクトのルートディレクトリに作成して、以下設定を記述します。タイムアウトの時間を10分に変更して、タイムアウトによるエラーを回避することができました。今回は、```@mui/icons-material/-/icons-material-5.14.11.tgz```という大きなパッケージをインストールするのに時間が掛かっていました。

```.yarnrc
network-timeout 600000
```

# 終わりに

```yarn install``` はプロジェクトに必要な依存パッケージをインターネットからダウンロードし、インストールするプロセスです。大きなパッケージを扱う場合、ネットワーク速度が遅い場合に時間が掛かるみたいです。その際は、タイムアウトの時間をさらに延ばして、回避できそうです。
企業ネットワークが原因で、Visual Studio CodeでGitHub Copilotが動作しない場合の対応方法（Windows向け）

# はじめに

UTM, SASE(CATO等), CASB(NetSkope等)などが導入された企業においては、[SSL/TLSインスペクション](https://e-words.jp/w/SSL%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%9A%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3.html)の影響で、`SELEF_SIGNED_CERT_IN_CHAIN`エラーが表示され、VisualStudio Code上でGitHub Copilotが動作しない、インラインチャットが動作しない等の問題が発生する場合があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/c0aea95a-2937-358d-88a4-9d0bf43106aa.png)

SSL/TLSインスペクションが行われる端末には、管理者によってネットワーク環境に応じた独自のCA証明書がインストールされます。これにより、VisualStudio Code本体はSSL/TLSインスペクションによる影響を受けません。

しかし、GitHub Copilotを含めVisualStudio Codeの機能拡張はそのCA証明書（独自のCA証明書）が参照されず、その結果上記のような問題が発生する場合があります。

# 対応方法
以下はWindows環境における対応方法になります。

１．[win-ca](https://marketplace.visualstudio.com/items?itemName=ukoloff.win-ca)機能拡張をインストールし、VisualStudio Codeを再起動する

２．設定を開き、`@ext:ukoloff.win-ca` と入力する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/22c66d70-7bb7-ec15-55ac-9d9b5708150f.png)

３．Injectを`append`に変更し、VisualStudio Codeを再起動する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/b42534d3-3fd5-967b-b105-50f4b6b36720.png)

４．GitHub Copilotが正常に動作することを確認する（以下はGitHub Copilot Chatで動作確認）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/64876/9ba2ea31-2420-3490-64a7-c9d708f040fc.png)

# 参考

https://stackoverflow.com/questions/71367058/self-signed-certificate-in-certificate-chain-on-github-copilot
YAMLの歴史と語源

# はじめに

身近で使用されているものの、よく知らないYAMLについて調べました。

あまり馴染みのない方に説明すると
- `docker-compose.yaml`（Dockerで複数のコンテナを同時に扱うためのファイル）
- Railsの`local`の記述
- mdエディタ「Obsidian」などで使われる`YAML frontmatter`

などで使用されています。

# 1. YAMLの歴史

公式サイトを要約すると以下のとおりです。

https://yaml.org/spec/1.2.2/

- 2001年：初期のフレームワークが作られる。言語はPerl
  XMLの簡素化などの目的があった。
- 2003年：Rubyが初めてYAMLをコア機能として採用
- 2004年：YAML 1.0を公開
- 2005年：YAML 1.1を公開
  この頃、JSONが注目され始める。全くの偶然だが、JSONはYAMLのサブセット（下位集合）と言えるものだった。
- 2009年：YAML1.2を公開
  YAMLをJSONの厳密なスーパーセット（上位集合）とすることが主眼。
- 2021年：YAML1.2.2を公開
# 2. YAMLの語源と意味

公式サイトから引用します。

> YAML (a recursive acronym for “YAML Ain’t Markup Language”) is a data serialization language designed to be human-friendly and work well with modern programming languages for common everyday tasks.

DeepLを参考に日本語に訳すと

**YAML（「YAMLはマークアップ言語ではない」の略）は、**
**人間にやさしく設計されたデータ・シリアライズ言語。**
**モダンなプログラミング言語でも動作し、日常的なタスクに使用される**

といったところでしょうか

シリアライズ言語についてはこちらに書かれています。

https://qiita.com/siakio/items/183b5f997123569e3ed2

引用すると

> # シリアライズとは

> 直列化を意味し、オブジェクトが持つデータをコンピュータが読み書きできるようにバイナリデータへ変換すること。  
> これによってデータをファイルとして保存したり、ネットワークで送受信できるようになる。  
> シリアライズ言語はシリアライズしたデータを表すためにフォーマット


また、シリアライズ言語の種類としてはYAMLの他にJSON・XMLがあります。
その関係性は、YAMLの歴史で述べたとおりです。

# おわりに

YAMLは「YAML Ain't Markup Language」の略、というのが面白かったです。
再帰的な頭字語、珍しい。

「Ain't Markup Language」とわざわざ言っているのも面白いですね。
「マークアップじゃないんだぞ！」というのが重要ポイント。

実は、初期には「Yet Another Markup Language」（もう一つのマークアップ言語）と呼んでいたらしいです。その否定の意味がある、と考えると納得の命名です。



さて、次は何を書こうかしら・・・
# 参考

https://yaml.org/spec/1.2.2/

https://learnxinyminutes.com/docs/yaml/

https://qiita.com/siakio/items/183b5f997123569e3ed2
【ChatGPT＋DALL-E3】企画その２がはじまりました😅


　どうも、カーブミラーです。

　今回は、X-Twitter上で、企画を開催します。前回同様、ファッションについて。今回は男性ファッションです。

:::note info
本記事は、ChatGPT（有料版）
＋DALL-E3で行なっております。
画像はあります。　あしからず。
:::

　まずは、ニュース？

　現在、X-Twitter上で、
　　“春のバン祭り”と称されるものが
　　　実施されています。

　ヤマザキの
　　“春のパン祭り”ではなく
　　　バン（BAN）ですw
　　　　“凍結祭り”とも
　　　　　呼ばれています。

　これは
　　X-Twitterが
　　　アカウントを
　　　　凍結してしまうものです。

　X-Twitterの健全性を
　　担保するためらしいですね。

　なので
　　こうした時期には
　　　ポストやコメントを
　　　　控えるのだ、
　　　　　と助言している人もいます。

　私もフォロワー数が
　　1500オーバーだったのが
　　　1300台前半に落ちました。

　まぁ、
　　自分がBANされなければ、
　　　とは思うのですが、
　　　　いつも交流してきた人が
　　　　　突然、パタリと無言になる
　　　　　　というのも
　　　　　　　心配になります。
***
　さて、
　　本題です。

　すでに、
　　X-Twitter上では、
　　　開催しておりまして、事前に
　　　　“男性ファッションだよ”と
　　　　　告知したおかげか、
　　　　　　募集をかけたら
　　　　　　　すぐさま反応を
　　　　　　　　いただきました。

　ええ、
　　応募作品が
　　　さっそくポストされています。
　　　　うれしいですね😄
***
　では、
　　詳細をお知らせいたします。

【週末恒例　カーブミラー企画その２】

　テーマ
　『#AI男性ファッション雑誌を飾ろう』

　前回は、女性オンリーでした。
　　意図したわけではないのですが、
　　　詳細説明中のテーマに“女”が
　　　　入っていたために
　　　　　オンリーになりました。

　ということで
　　今回は【男性に限定】します。

　企画内容の詳細は、
　　下記のとおりです。
　　（画像のALT（代替）と同じ内容）
***
テーマどおりです。雑誌を作るわけではありませんが、ファッション雑誌に載せるようなものをお願いします。

❌禁止事項❌←これは守ってね
・人型以外はダメ
　（イカ・タコ・キノコなんかはダメw）
　（でも、人型の頭に使う分にはOK）
・水着、下着、中高の制服
・プラグスーツ的な
　　身体のラインだけのものはダメ
・ウェディングドレスもダメ
・ビジネスやホストのスーツ、三つ揃い
　（Ｙシャツだけなんかも含む）
・Ｔシャツ、それだけではダメ
・スポーツウェアもダメ
・スウェットもダメ

　とにかく、
　　そんなのファッション雑誌に
　　　載せないでしょ的なものは
　　　　却下です。

ファッション雑誌の服装には、
　裸同然のものがありますが、
　　今回は、なし、でお願いします。

背景や場所は、
　自由に設定してください。
　　公衆浴場とかは、なしでw

ファッションショーでも
　街歩きでも、ご自由に。

あなたの発想を写真・絵・画像・動画にしてください。手描きOK。枚数制限なし。

あっ、ネガティブはダメですよ〜。
　センシティブなものはダメですよ〜。

企画終了は、2024/04/07(日)24時。
今から【金土日の三日間のみ】です。

仕事終わりや家族奉仕終わりにでも参加してくださいね😄　疲れてそれどころじゃないかw


なお、私をフォローしなくてもOK
　それが目的ではないのでw


以下のことを忘れずにポストして。

・テーマ（必須）
　『#AI男性ファッション雑誌を飾ろう』
　（↑これは必ずシャープをつけてね）

・服装の説明
　（あった方がいいけれど）

・この返信のリンク（引用）
　（やり方わからなければOK。
　　テーマでチェックします）

・写真・絵・画像・動画（必須）

を貼ってポスト。
初めての人でも挨拶はいりません。
どんどんとアップしてください。
バンされないレベルでw

なるだけ、コメントします。
少なくとも、いいね、はしたいです。

最後に、これは優劣を決めるものではありません。また、フォロワーを増やしたくてやるものでもありません。よろしくお願いいたします🙇

なお、今回のファッ ションは、今後使わせていただく可能性があります。その際は引用します。
***

　ということで、
　　前回の女性よりも
　　　制限を多くしたために
　　　　平々凡々な服装しか
　　　　　集まらない気がしています。

　その分、
　　楽なのですがw

　だって、
　　対応が大変なのですよ😅
　　　ポストされたら
　　　　その画像をチェックして
　　　　　コメントを返さねば
　　　　　　ならんのですから。

　まぁ、
　　それがまた楽しくて、
　　　やっているんですけどね😄

　みなさんも
　　当てはまるような作品が
　　　ありましたら、ポストして
　　　　ください。
***
　この企画が
　　みなさんの作品制作の
　　　刺激になれば、幸いです。

　今回は、ここまで。

　この画像は
　　企画募集に使っているものです。
![1712284161945.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457238/b8071a7c-7170-e4ae-5a71-21ac6ead896e.jpeg)
「MCP9700サポート」Temperature MCP9701 MCP9700 の関数化(浮動小数点)(StampS3)(リッチプログラミング)(マクロ)

目的
ADCのテスト

結果


![o_coq018.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0d934b96-dc97-91df-d6fc-65c270917a9d.jpeg)

![o_coq019.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/875d3970-ab2a-0dba-1e8f-96eb168ef44d.jpeg)



プログラム


```c++


//SER_Temperature_MCP9701_M5S3_1


//インクルド
#include <Arduino.h>
#include "Temperature_MCP9701_MCP9700.h"


//初期化処理
void setup()
{

  //シリアルの初期化
  Serial.begin(9600);

} //setup


//メインループ
void loop()
{

  //センサーの値を読み込む
  int Sensor = analogRead(5); // センサーの読み取り値
  //温度の表示
  float Voltage = Sensor * ( 3.3 / 4096.0 );
  float Temperature = Temperature_MCP9701(Voltage);
  Serial.println(Temperature);

  //1秒の待ち
  delay(1000);

} //loop




```


Temperature_MCP9701_MCP9700.h


```c++


// Temperature_MCP9701_MCP9700.h 
//
// ex 3.3V analogReadResolution(12);
//         float Sensor = analogRead(A2);
//         float Voltage = Sensor * ( 3.3 / 4096.0 );
//         float Temperature = Temperature_MCP9701(Voltage);
//
float Temperature_MCP9701(float Voltage){

  return((Voltage - 0.4) * (1.0 / 0.0195));

}//Temperature_MCP9701


float Temperature_MCP9700(float Voltage){

  return((Voltage - 0.5) * (1.0 / 0.01));

}//Temperature_MCP9700


#define Temperature_MCP9701_A0() Temperature_MCP9701(analogRead(A0)*(5.0/1024.0))
#define Temperature_MCP9701_A1() Temperature_MCP9701(analogRead(A1)*(5.0/1024.0))
#define Temperature_MCP9701_A2() Temperature_MCP9701(analogRead(A2)*(5.0/1024.0))
#define Temperature_MCP9701_A3() Temperature_MCP9701(analogRead(A3)*(5.0/1024.0))
#define Temperature_MCP9701_A4() Temperature_MCP9701(analogRead(A4)*(5.0/1024.0))
#define Temperature_MCP9701_A5() Temperature_MCP9701(analogRead(A5)*(5.0/1024.0))

#define Temperature_MCP9700_A0() Temperature_MCP9700(analogRead(A0)*(5.0/1024.0))
#define Temperature_MCP9700_A1() Temperature_MCP9700(analogRead(A1)*(5.0/1024.0))
#define Temperature_MCP9700_A2() Temperature_MCP9700(analogRead(A2)*(5.0/1024.0))
#define Temperature_MCP9700_A3() Temperature_MCP9700(analogRead(A3)*(5.0/1024.0))
#define Temperature_MCP9700_A4() Temperature_MCP9700(analogRead(A4)*(5.0/1024.0))
#define Temperature_MCP9700_A5() Temperature_MCP9700(analogRead(A5)*(5.0/1024.0))



```
【HTML,CSS】HTMLのページ内に外部のサイトにアクセスするボタンを設置する方法 #2

# はじめに
こんにちは! 中学2年生のWardHamatsu67です! 今回は、前回の続きで、CSSも使って見た目を本当のボタンにしていきたいと思います。
# コード
```html
<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8"/>
    </head>
    <link rel="stylesheet" href="sample.css"/>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Klee+One&family=Zen+Maru+Gothic&display=swap" rel="stylesheet">
<body>
    <p class="colorful">明けまして
        <span>お</span>
        <span>め</span>
        <span>で</span>
        <span>と</span>
        <span>う</span>
        ございます。</p>
    <p></p>
        <a href="./blue.html" class=class="btn btn--orange btn--radius">ここから</a>
</body>
</html>
```
CSSのクラスを読み込むところを追加しただけで、他は前回と変わりません。
```css
    .colorful {
        font-family: "Klee One", cursive;
        font-weight: 400;
        font-style: normal;      
    }
    .colorful span:nth-child(6n+1){color: #ff0000;}
    .colorful span:nth-child(6n+2){color: #00ff00;}
    .colorful span:nth-child(6n+3){color: #0000ff;}
    .colorful span:nth-child(6n+4){color: #aa0000;}
    .colorful span:nth-child(6n+5){color: #00aa00;}
    .btn--orange,a.btn--orange {
        font-family: 'Klee One', cursive;
        font-family: 'Shippori Mincho', serif;
        color:#00bfff;
        color: #f2f;
        background-color: #abd100;
        }
    .btn--orange:hover,a.btn--orange:hover {
                        color: #fff;
                        background: #a6e500;
                        }

    a.btn--radius {
    border-radius: 100vh;
    }
```
CSSで色や角をどのくらい丸めるのかを設定していきます。
今回はボタンの色を少し濃い黄緑色に、「ここから」の文字を少し濃いピンクにしました。
# 完成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/e28ff062-9b55-656e-0e71-ff763beb463e.png)
ボタンのデザインを変えただけなのに、結構、全体の見た目が変わったように見えますね。もちろん。、「ここから」を押すと...
![スクリーンショット 2024-03-26 185216.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/ffdd9e50-9283-737f-97cf-c3b1daba6d6b.png)
こうなります。
# おわりに
いかがでしたか。なんか前回の投稿から今回までが結構早かったと思います。今回のはCSSが結構面倒ですが、青看板などと比べたら簡単です。
この記事が良いと思った方はいいねとフォローをしてくれると嬉しいです。
実行ポリシー実験　自己著名証明書作成

PowerShell 7.4.1で実行
```
PS C:\Users\（ユーザ名）>cd C:\Users\（ユーザ名）\Desktop\実行ポリシー実験

PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> $cert = New-SelfSignedCertificate -Subject "CN=hoge" `
                -KeyAlgorithm RSA -KeyLength 2048 -Type CodeSigningCert `
                -CertStoreLocation "Cert:\LocalMachine\My\" -NotAfter 2040/12/31
PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> Move-Item "Cert:\LocalMachine\My\$($cert.Thumbprint)" "Cert:\LocalMachine\Root"
PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> $cert=Get-ChildItem Cert:\LocalMachine\Root -CodeSigningCert
PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> $cert.Thumbprint[0]
文字列




PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験>$directoryPath = "Cert:\CurrentUser\Root"
PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験>$fullPath = Join-Path -Path $directoryPath -ChildPath $cert.Thumbprint[0]
PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> Set-AuthenticodeSignature -FilePath C:\Users\（ユーザ名）\Desktop\実行ポリシー実験\test3.ps1 -Certificate (Get-ChildItem -Path $fullPath)

    Directory: C:\Users\（ユーザ名）\Desktop\実行ポリシー実験

SignerCertificate                         Status                    StatusMessage             Path
-----------------                         ------                    -------------             ----
文字列  Valid                     Signature verified.       test3.ps1

PS C:\Users\（ユーザ名）\Desktop\実行ポリシー実験> .\test3.ps1
Hello World!!
```
【HTML】HTMLのページ内に外部のサイトにアクセスするボタンを設置する方法 #1

# はじめに
こんにちは! 投稿をしばらくサボっていた中学2年生のWardHamamatsu67です! 今回は、自分のHTMLのページに、外部のサイトにアクセスできるボタンを設置する方法を紹介したいと思います。Wikipediaなどでよく見かけるものですね。
# コード
今回はこの前の記事で使用した「明けましておめでとうございます。」が書かれたページから青看板があるページにアクセスするボタンを作ります。
```html
    <p></p>
        <a href="./blue.html">ここから</a>
```
ボタンを作るときにはaタグが必要になります。
"href="の後には、"./ファイル名"と書きます。
そして、ボタンを作るときに注意することがあります。それは、aタグとその閉じタグの間に<font color="red">文字を書かないといけないことです!!</font>この作業をしないと、どこにボタンがあるのかがわからなくなるからです。
# 完成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/ecbee9e7-a14f-7711-7b90-294db98ade53.png)
「ここから」というボタンが設置されていますね。ではこれを押すとどうなるでしょうか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3749972/1f2ed2ec-bdfa-eb6c-8787-357fca6c4d12.png)
はい。無事アクセスできました。
# おわりに
どうでしたか。しばらく投稿をサボっていたので何か難しいことを紹介するのかと思ったら、かなり簡単なことを紹介して...!と怒る方もいらっしゃると思いますが、長い間サボることにならなくてよかったです。次回は、これにCSSを合わせたバージョンを紹介したいと思います。
この記事が良いと思った方はいいねとフォローをしてくれると嬉しいです。
GoogleColaboでzipファイル解凍

# はじめに
機械学習コンペでデータがzipファイルで与えられることありますよね。
GoogleColaboでの解凍方法の備忘録です。

# 解凍方法
### ローカルのzipファイル
①GoogleColaboにzipファイルをアップロード
②zipファイルのパスを右クリックでコピー
③```!unzip```で解凍

```sh
!unzip '/content/hoge.zip'
```

### URLのzipファイル
①zipファイルのURLをコピー
②```!wget```でGoogleColaboにコピー
③zipファイルのパスを右クリックでコピー
④```!unzip```で解凍

```sh
!wget 'https://fuga'

!unzip '/content/hoge.zip'
```

# おわりに
以上です。良い機械学習ライフを！

次の記事でお会いしましょう('ω')ノ
Canvasから画像へ、そして圧縮：JPEG対PNG

### このブログの内容:
1. HTMLコンテンツから画像ファイルを生成するプロジェクトの事例紹介。
2. PNGとJPEG画像を圧縮する方法についての考察。
3. パフォーマンスとサイズのバランスをどう取るか。

ウェブ開発では、画像を使う際に品質とパフォーマンスのバランスを見つけることが大切です。最近、HTMLコンテンツから大きな画像を生成する必要があるプロジェクトに取り組みました。その過程でhtml2canvasライブラリを利用しました。これはDOMの一部をキャンバスに表示し、HTMLCanvasElement.toBlob()を使ってキャンバスからblobを作成し、HTMLを画像に変換します。使い方は以下の通りです：


```javascript
toBlob(callback)
toBlob(callback, type)
toBlob(callback, type, quality)
```

## PNGを選んだ理由
私のコードでは、toBlob()メソッドを次のように使用しました：

``` javascript
  const blob = await new Promise<Blob>((resolve, reject) => {
    canvas.toBlob((blob) => {
      if (blob) {
        resolve(blob);
      } else {
        reject(new Error('Failed to convert canvas to Blob.'));
      }
    }, 'image/png');
  });
```

プロジェクトで扱う元の素材がたまたまPNG形式の画像だった。ユーザーの操作によってこれらの画像を重ね合わせ、最終的な画像を作成する際にもPNGを選びました。上記のコードで示すように、それは十分に簡単でした。しかし、このPNG形式での画像生成方法では、生成された画像のサイズが最大で6MBになる場合があることに気づきました。

## JPEGの選択

JPEG形式の選択を最初から検討していれば、より効率的にプロジェクトを進められた可能性があります。JPEGは品質レベルをサポートしており、toBlobの第三の「quality」パラメータを利用することができます。このパラメータは0から1の間の数値を取り、品質とファイルサイズのバランスを取るのに役立ちます。こちらがその例です：

```javascript
return await new Promise<Blob>((resolve, reject) => {
  canvas.toBlob((blob) => {
    if (blob) {
      resolve(blob);
      } else {
        reject(new Error('Failed to convert canvas to Blob.'));
      }
    }, 'image/jpeg', 0.9); // <- quality (0-1)
  });
```

0.9という値が良いバランスだとわかりました。これで、同じキャンバスから作成された6MBのPNG画像と見分けがつかない1MBの画像を生成することができました。これにより、私の目標であったAWS Lambdaのペイロード制限（6MB）を下回ることができました。0.8から0.5までの値で実験しましたが、0.5でも画像品質の損失に気づかず、ファイルサイズの削減がパフォーマンスを大幅に改善するわけではなかったので、画像が悪くなるリスクを冒す価値はないと判断しました。

## PNGを使う試み
しかし、すぐにJPEGを選択するわけではありませんでした。最初の反応はPNG画像を圧縮しようとすることでした。そのために、UPNGというパッケージを見つけました。こちらがそのコードです：

```javascript
import UPNG from 'upng-js';

const arrayBuffer = await blob.arrayBuffer();
const img = UPNG.decode(arrayBuffer); 
const rgba = UPNG.toRGBA8(img)[0];
const compressedData = UPNG.encode([rgba], img.width, img.height, 256); // <- color palette 
const compressedBlob = new Blob([compressedData], {type: 'image/png'});
return compressedBlob
```

このコードがファイルサイズを減らす方法は、色の範囲を256色パレットに減少させることによります。この追加のステップによって、元の6MBの画像が2MBにまで減少しました。色圧縮されたPNG画像では、異なる色合いの間の遷移がかなり急になります。これにより、元のデザインにはなかった線のようなテクスチャが生じます。これらの線の目立ち方は、開発者が通常コントロールできないソース素材に大きく依存します。

下の画像がかなりズームインされており、効果が強調されています。

![compression comparison.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3588855/247d2989-f878-afa7-9011-67e23b343a7f.png)


PNGをこのように圧縮しても、後でJPEGで達成したものの約2倍のサイズで画像が出てしまいました。その上、追加ステップは画像処理時間に少し余分な時間を要しました。

私が学んだことは、PNGは無損失(lossless)フォーマットであるということです。JPEG画像は保存時にわずかな品質を失うのに対し、PNGはそのような問題がありません。しかし、圧縮の選択肢が限られているため、品質を保証することはサイズの増加を意味します。

## 結論

PNGとJPEGはそれぞれ特有の利点があり、プロジェクトの要件に応じて適切なフォーマットを選択することが重要です。この経験から、ファイルサイズと画像品質のバランスを考慮しつつ、プロジェクトの目的に最適な画像フォーマットの選択がいかに重要であるかを学びました。
Haskellのdo記法がよくわからなかった話

# はじめに
どうも Haskell 初心者です！
最近『すごいHaskellたのしく学ぼう』を勉強しました。私にとっては初めての関数型言語だったので理解で苦しむところも多くありました。

なかでも、モナドのdo記法のところで混乱したので、私が何に混乱したのかを書いておきます。

# 誤解のもと
8章の入出力の章で初めてdo記法が出てきたときは、この様なコードが載っていました。
```hs
main = do
    putStrLn "Hello, what's your name?"
    name <- getLine
    putStrLn ("Hey " ++ name ++ ", you rock!")
```
これを見て私は
- do記法の中では、`<-`を使うことで`IO()`とかいう良くわからないものを剥がして代入してくれるんだな
- do式の最後の行が返り値になるんだな

と思っていました。

# 認識違いの判明
ところが13章のモナドの章でその認識では説明できないコードが現れました。
```hs 
-- landLeft :: Int -> (Int, Int) -> Maybe (Int, Int)
-- landRight :: Int -> (Int, Int) -> Maybe (Int, Int)

routine :: Maybe (Int, Int)
routine = do
    start <- return (0, 0)
    first <- landLeft 2 start
    Nothing
    second <- landRight 2 first
    landLeft 1 second

{-
ghci> routine
Nothing
-}
```
なぜか途中にあって何にも束縛していない`Nothing`がdo式の返り値に影響を与えているのです！
ただ、当時は自分の理解と矛盾していることにも気がついておらずスルーしていました。

14章でも
```hs
logNumber :: Int -> Writer [String] Int
logNumber x = writer (x, ["Got number: " ++ show x])

multWithLog :: Writer [String] Int
multWithLog = do
    a <- logNumber 3
    b <- logNumber 5
    tell ["Gonna multiply these two"]
    return (a*b)

{-
ghci> runWriter multWithLog
(15, ["Got number: 3", "Got number: 5", "Gonna multiply these two"])
-}
```
またしても`tell`という、どの変数にも束縛されてない関数がしっかり結果に影響を与えているのです！
これを見て私も自分の認識がおかしいことに気が付きます。

# do記法を脱糖してみる
do記法は糖衣構文なので、脱糖して書いてみます。それぞれ

```hs
routine :: Maybe Pole
routine = return (0, 0) 
        >>= landLeft 2 
        >> Nothing 
        >>= landRight 2 
        >>= landLeft 1
```

```hs
runWriter (logNumber2 3 >>= (\x
        -> logNumber2 4 >>= (\y
        -> tell ["Gonna multiply these two"] >> return(x * y) )))
```
と同じコードということになります。こう書くと独立していて何もしていないようにみえた`Nothing`や`tell`も一連のモナド適用の連鎖の一部であることがわかります。

# おわりに
do記法は手続き型言語のような見た目をしていますが、各行は独立しておらず、滝のように連なっていることがわかりました。
自分と同じ勘違いをしている初心者の助けになれば幸いです。
Googleカレンダーから当日予定を取得し、任意のLINEに送信するBot

Googleカレンダーから当日の予定を取得し、任意のLINEに送信するBotをGASで作成しました。

下図のように、任意の時間帯にLINEに当日予定を送信することが出来ます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/984a618a-80eb-1dde-0c10-afe138d7b2b1.png)

通常、この類の通知自動化はLINE Notify上で行うケースが多いかもしれませんが、このBotでは任意のLINEに対して送信することが出来ます。

また、先日記述したこちらのGooglカレンダー自動登録プログラムと組み合わせると、非常に有用かと思います。
https://qiita.com/ussoewwin/items/c73525855d96fbb0fed3

まず始めに、GASで新しいプロジェクトを作成し、下のコードを貼りつけてください。
```main.gs
// Google カレンダーから当日の予定を取得する関数
function getTodaysEvents() {
  const calendarId = 'sample@gmail.com'; // Google カレンダーのID
  const calendar = CalendarApp.getCalendarById(calendarId);
  const today = new Date();
  const events = calendar.getEventsForDay(today);
  let message = '本日の予定は以下の通りです：\n';
  
  if (events.length > 0) {
    for (let i = 0; i < events.length; i++) {
      const event = events[i];
      const title = event.getTitle();
      const startTime = Utilities.formatDate(event.getStartTime(), Session.getScriptTimeZone(), 'HH:mm');
      const endTime = Utilities.formatDate(event.getEndTime(), Session.getScriptTimeZone(), 'HH:mm');
      message += `${startTime} - ${endTime}: ${title}\n`;
    }
  } else {
    message += '予定はありません。';
  }
  
  return message;
}

// LINEにメッセージを送信する関数
function sendLineMessage(message) {
  const CHANNEL_ACCESS_TOKEN = 'ここに入力する'; // LINE Botのアクセストークン
  const userId = 'ここに入力する'; // 送信先のユーザーID
  const url = 'https://api.line.me/v2/bot/message/push';
  const headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + CHANNEL_ACCESS_TOKEN,
  };
  const postData = {
    to: userId,
    messages: [{
      type: 'text',
      text: message,
    }],
  };
  
  const options = {
    method: 'post',
    headers: headers,
    payload: JSON.stringify(postData),
    muteHttpExceptions: true,
  };
  
  UrlFetchApp.fetch(url, options);
}

// トリガー用のラッパー関数
function sendTodaysEventsToLine() {
  const message = getTodaysEvents();
  sendLineMessage(message);
}
```

カレンダーID、LINEのアクセストークン、LINEユーザーIDの入力が必要です。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/9a8e80ee-d100-1f20-73a4-54f58a6fce44.png)


カレンダーIDは、Googleカレンダーの設定画面から確認することが出来ます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/fee16277-e980-3ba0-9eb0-754e70a3551a.png)

次に、トリガーを設定します。

まず、下図のように実行関数は「sendTodaysEventsToLine」を指定し、イベントソースは「時間主導型」に設定します。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/5f2e568d-355a-1d7a-2ee2-96b42fc3bcb1.png)

時間設定は、自由に希望の時間帯や実行間隔を設定してください。
![タイトルなし1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/ab28c7fb-be86-ea68-8e9a-be8ada488839.png)

これでコードの準備は完了したので、ウェブアプリとしてデプロイを行い、初回のアカウント承認を実行してください。

コードそのものはトリガーで動作するので、LINE DevelopersのWebhookにリンクさせる必要はありません。

１日の中に複数のスケジュールが入力されている場合でも、下図のようにまとめて送信されます。
![タイトルなし.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3661150/984a618a-80eb-1dde-0c10-afe138d7b2b1.png)
Google Apps ScriptをVSCodeで編集する

## 事前準備

- Node.jsがまだインストールされていない場合は、インストールしてください。
- VSCodeを入手してください。

## Google Apps Script APIをオンにする

下記にアクセスしてオンにする  
https://script.google.com/home/usersettings  

![GAS-API.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19174/4d777e77-6ce3-ccf3-4ac4-49cb4a89400a.png)

## claspのインストール

ターミナルで以下のコマンドを実行。ターミナルの再起動が必要？

```
npm install -g @google/clasp
```

## Googleアカウントでclaspにログイン

次のコマンドを実行して、Googleアカウントでclaspにログインします。

```
clasp login
```

ブラウザが開き、Googleアカウントでのログインを求められます。


## GASプロジェクトのクローン

- 既存のプロジェクトを編集する場合は、プロジェクトのスクリプトIDを使用してクローンします。  
- スクリプトIDは、Apps Scriptエディタの「プロジェクト設定」から確認できます。

```
clasp clone {スクリプトID}
```


## VSCodeで編集

claspを使用してローカルにダウンロードしたスクリプトファイルをVSCodeで開いて編集します。

## 変更のプッシュ

スクリプトに加えた変更をGoogle Apps Scriptに反映させるには、以下のコマンドを使用します。

```
clasp push
```
シリーズ：Rのwarning①

Rの警告（warning）は基本的に無視してきたが、時々無視してはいけないものがあるので、シリーズとしてまとめることにする。みなさんの経験もコメントにいただけると嬉しい。

本シリーズ第１段として、シングルセル解析で用いるSeuratのSCTransformでみられた警告を取り上げる。

# SCTransformについて
SCTransformとはscaling+normalizationを行う比較的新しい手法
Seuratではassayというスロットにカウントデータが格納されるが、SCTransformを行った後はSCT assayというスロットにnormalize後のカウントデータが格納されている。

# 無視してはいけない警告
今回無視して痛い目をみたのは以下の警告である。
``` R:
markers <- FindAllMarkers(seurat.obj, only.pos = TRUE, assay = "SCT", slot = "scale.data")
#警告:  No DE genes identified
#警告:  The following tests were not performed: 
#警告:  When testing XXX versus all:
#Object contains multiple models with unequal library sizes. 
#Run `PrepSCTFindMarkers()` before running `FindMarkers()`.
```
えっ？明らかに発現差のあるクラスター間で発現変動遺伝子がゼロはおかしいでしょ。。。
PrepSCTFindMarkers()ってなんですか。。。

というわけで、警告を無視せずやってみると、
``` R:
seurat.obj <- PrepSCTFindMarkers(object = seurat.obj, assay = "SCT", verbose = T)
#Found 21 SCT models. Recorrecting SCT counts using minimum median counts: 21
#  |++++++++++++++++++++++++++++++++++++++++++++++++++| 100% elapsed=21s 

markers <- FindAllMarkers(seurat.obj, only.pos = TRUE, assay = "SCT", slot = "scale.data")
#Calculating cluster XXX
#Calculating cluster YYY
...
```
※今回はlayerを21グループにsplitしている

無事にできた！

``` R:
# 各グループのtop10を抽出
markers %>%
  group_by(cluster) %>%
  dplyr::filter(avg_diff > 1) %>%
  slice_head(n = 10) %>%
  ungroup() -> top10

# DotPlot
DotPlot(seurat.obj,
        features = unique(top10$gene),
        group.by = "cluster"
)&
  scale_color_gradient2(high = "firebrick1", mid = "snow2", low = "dodgerblue2", midpoint = 0) &
  theme(axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1))
```

みなさんも気を付けましょう。。
※PrepSCTFindMarkersについては深堀してない、、
python-docxでワードのヘッダー、フッターを各セクションごとに違う値にする

# はじめに
ワードの文書作成の自動化というのは、結構あるあるだと思う。
筆者はpythonを主に使用するので、python-docxで自動化するかーと軽い気持ちでやっていたが、思ったより大変だったので、今回躓いた内容を記しておく

ちなみに、公式ドキュメントを自分で漁れる、または躓いたところなんてオプションをちゃんと見れば解決できるっしょ！という、つよつよエンジニア向けではないのであしからず...当方、社会人になってからプログラムをやっている雑魚エンジニアなので、公式ドキュメントを見てばっちり分かるタイプではないんや...

# 躓いた内容
ワードの文書でヘッダー、フッターというのがある。主にページ数とかを書くものである。
今回は、そのフッターに各ページごとに違う文字を入れたい！と思っていたが、とりあえず作ったものでは全く機能しなかった。
すべてのフッターの値が、最後に更新した値になっていたのである。

# 解決策
解決した際のコードを貼っておく
``` python
import docx  # python-docxのインポート

# 新しいワードの作成
doc = docx.Document()
section = doc.sections[-1]  # 最後のセクションを取得

for footer_text in ["a", "b", "c"]:
    # 新しいセクション(ページ)の追加
    section = doc.add_section(docx.enum.section.WD_SECTION.NEW_PAGE)
    
    # フッターの指定
    footer = section.footer

    # 前セクションとのリンク切り離し
    footer.is_linked_to_previous = False

    # フッターへ文字を入力
    footer.paragraph[0].text = footer_text

doc.save("hoge.docx")

```

重要なのは新しいセクションの追加と、前セクションとのリンクの切り離しになっていて、
そもそも新しいセクションでないと、ヘッダー・フッターの値はすべて同一になってしまうし(これはワードを実際に手で動かしてもそうなる)、リンクの切り離しをしないとやっぱり同一の値になってしまう。


# おわりに
今回は、python-docxのヘッダー、フッターというとても狭い領域の内容だったが、日本語で探しても解答が出てこないな...という印象。だいたい「フッターに任意の文字を入れる！」といった基本内容しか書いていなく、英語で探さないと出てこない。
公式ドキュメントも、質問内容で検索したって望むオプションとかはわからないので、stackoverflowとかで検索して使えそうなオプションを試す、を繰り返して見つけた...

chatGPTにも聞いたが、python-docx系のかなり踏み込んだ仕様には解答できていない印象。英語で聞けば違ったかもしれない
ワンクリックでVPN接続/切断を切り替える in Windows11

## VPN接続/切断がめんどくさい
リモートワークの関係上、VPNはほぼ必須になっていますが、作業してると一度VPNを切断したいときが結構あります
その都度、以下の4クリックをするのが非常にめんどくさいです
`タスクバーの通知領域メニュー → VPN → VPN選択 → 接続or切断`
なので、ワンクリックで済むようバッチファイルを作りました

## バッチファイルの中身
```
@echo off
ipconfig | find "Luxiar" > nul
if %ERRORLEVEL% == 0 (
    rem "Luxiar VPN 接続済なら切断"
    rasdial.exe Luxiar /DISCONNECT
) else (
    rem "Luxiar VPN 未接続なら接続"
    rasdial.exe Luxiar
)
```
VPN接続名は「Luxiar」(弊社名)であり、ipconfigの結果にVPN接続名が現れているかを判定しています
`rasdial.exe` を使用して接続/切断をコントロールしています、接続時(8行目)ではユーザー名とパスワードが必要になる場合もあります

## バッチファイルをタスクバーに登録する
バッチファイルのショートカットを作成し、プロパティからリンク先の編集をします
頭に `cmd.exe /c ` をコピペして適用
/cの後にはスペースが入ります
![スクリーンショット 2024-04-05 102023.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525595/91e8346a-9def-21f9-e6c8-2290adc58e14.png)

作成したショートカットをタスクバーへドラッグ&ドロップ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3525595/08ba3846-da64-1346-4e97-0e1564344984.png)

タスクバーのショートカットをワンクリックでVPN接続/切断を切り替えることができるようになりました
k8sでAPIに対してfetchしたがInvalid URLエラーが出る

# はじめに

kubernetesの他のポッドで立てているAPIにリクエストするのにすこしはまったので一応書いておきます

# 問題

以下のようにfetchをjsで行いました

```ts
  const response = await fetch(`${process.env.HOST}/api/users/login`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
```

ここでHOSTはdeploymentにvaluesで渡していました

```yaml:values.yaml
HOST=hoge.hoge.svc.cluster.local
```

しかしfetchでエラーが出ました

```
TypeError: Invalid URL
    at new URL (node:internal/url:775:36)
    at new Request (/usr/src/app/node_modules/@remix-run/web-fetch/src/request.js:81:16)
    at /usr/src/app/node_modules/@remix-run/web-fetch/src/fetch.js:43:19
    at new Promise (<anonymous>)
```

# 解決方法

慣れないk8sなのでそもそも名前解決できてないのではと思っていましたが、よくエラーをみるとURL形式で怒られていました

つまり`http://`が存在していなかったのが問題でした

ちゃんとエラーをみていけばすぐ解決できました

# おわりに

k8sにかなり慣れてきたので楽しくなってきました
Playwright – FullPage指定のスクリーンショット撮影で意図しないマウスオーバー効果・ブラウザサイズ変更が起こってしまう

Playwrightの操作動画を記録してみて分かったのだが、Playwright は fullPage のスクリーンショット撮影の時、ブラウザサイズを変更することでスクリーンショット撮影を実現してそうな気がする

このため

- 意図しないブラウザサイズ変更がおこなわれる
- 副作用でカーソル位置が変わってしまう

という現象が起きていそうだった

カーソル位置の問題に関しては、スクリーンショット撮影前にカーソル位置を左上に移動させておくことで、問題を抑止しやすくなるかもしれない

```js
await page.mouse.move(0, 0)

await page.screenshot({
  path: `foo.png`,
  fullPage: true,
})
```


# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# プロフィール・経歴

https://github.com/YumaInaura/YumaInaura
【Swift】shared?? シングルトンをわかりやすく解説

#　目次
1. [シングルトンとは何か？](#anchor1)
2. [モーダルのカスタム](#anchor2)
3. [さいごに](#anchor3) 

<a id="anchor1"></a>
# 1. シングルトンとは何か？
オブジェクト指向プログラミングをしていると、クラスファイルからインスタンスを生成してメソッドを利用することが基本形です。
ここでご質問です。プロジェクト全体で見た時にクラスAのインスタンスは何個ありますか？？
そのインスタンスがシングルトンで設計してあれば、答えはひとつです！
つまり、`シングルトンとはインスタンスがひとつしか存在しないことを保証する設計方法のこと`です。

<a id="anchor2"></a>
# 2. シングルトンの実装手順
以下のクラスをシングルトンに設計しなおします。
```Swift: Members.swift
public class Members {
    init() {}
    private let members: [String: Int] = ["Suzuki": 21, "Takashima": 30]
    public func showAge(name: String) {
        print(members[name]!)
    }
}

let members = Members()
members.showAge(name: "Suzuki")
```
```Swift:実行結果
21
```
### 1. finalを付与する
シングルトンは継承禁止です。継承されてしまっては、１クラス１インスタンスで設計しているのに、親戚ができてしまったら困ります。
```Swift
final public class Members {
```
### 2. initをprivateにする
イニシャライザをprivate化することで、絶対にクラスの外部からアクセスできないようにします。
```Swift
private init() {}
```

### 3. 外部からの唯一の入り口を設置
シングルトンにしたいクラスは継承もできない、イニシャライズもできない、ということで外部からの入り口を作ってあげる必要があります。`public staticプロパティ`を使用します。
その変数名は`shared`とするのが一般的です。

補足： `static`はスレッドセーフな修飾子です。iOSアプリは基本マルチスレッドプログラミングで実装するので、同時に違う処理が動いていることが多いです。なので、このマルチスレッドで処理が動いた時に複数のスレッドからstatic変数にアクセスされたとしても、ひとつしか変数が存在できません。

```Swift
public static let shared = Members()
```

### 4. まとめ
これまでのコードをまとめると以下のようになります。
```Swift: Members.swift
public class Members {
    private init() {}
    private let members: [String: Int] = ["Suzuki": 21, "Takashima": 30]

    public static let shared = Members()
    public func showAge(name: String) {
        print(members[name]!)
    }
}

Members.shared.showAge(name: "Suzuki")

```
sharedを介してしか、アクセスできなくなりました！
そしてインスタンスはただひとつ`public static let shared = Members()`のみです！
<a id="anchor3"></a>
## さいごに
シングルトンとは名前の通りで、クラスのインスタンスがひとつ(シングル)しか存在しないことを保証する設計方法でした。名前の割に単純です！
パーティクルフィルタとは

# パーティクルフィルタとは

パーティクルフィルタ（粒子フィルタ モンテカルロフィルタ）とは点の密度を元にして、確率密度を生成、そして次に導出されるであろう値を推定する時系列データと推定手法の一つです

## 有効な推定対象

- 非線形
- 非ガウス性
- 時系列データ

## アルゴリズムの手順

1. 初期化
2. 予測
3. 更新
4. リサンプリング

## 開発者が決定する関数

- モデルから次に期待される生データを予測する**システムモデル**
- 生データとモデルがどれだけ一致しているかを導出する**尤度関数**

# 具体例を交えた説明

## 目的

電波反射を用いて t 秒後の位置を推定したい

## 条件

- 電波は 10 回スキャンするとする

### 1. 初期化

予測済み、0 秒時のモデルを確認

![スクリーンショット 2024-04-05 8.06.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839531/0acd6ce8-b43c-1a79-eddd-a1510a7269e5.png)

### 2. 予測

では、電波の発信地に近づく方向で進んだ時の t 秒後の電波強度（生データ）の形がどうなっているか予測してみます

#### 2-1. 0 秒時のモデルを元に次にどんな生データが生成されそうか予測

発信機に近づく方向での生データを予測するため全体的に右にずれた生データが期待できそうです

こんな感じのデータ
![スクリーンショット 2024-04-05 8.22.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839531/5f3a8996-96eb-49c7-1a04-0bc0bffe12bb.png)

**全体的に右にずれた生データが期待できそう**のように現在のモデルから何かしらの処理を加えて次の生データを予測する処理（システムモデル）は開発者が決定します

### 2-2. 実際のデータと比較

![スクリーンショット 2024-04-05 8.27.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2839531/e54f5edc-2e1b-acf4-cac0-dba9a5377f86.png)

ここで、尤度関数を用いて予測した生データと実際の生データがどれだけ一致しているか計算します

> ### 補足
>
> 尤度とはモデルの当てはまり度、一致率のことです
> 値が大きければ大きいほどモデルとの当てはまりが良いとされるので厳密には異なりますが、損失関数の逆といってもいいです

予測した生データと比べて実際の生データは電波強度の分布が全体的に若干左にはよっていますがおおかた推定できていそうです

### 3. 更新

モデルとして適用するデータを 2 で推定したデータに変更します

### 4. リサンプリング

重みを考慮して再度モデルを生成、1 に戻ります

以上を繰り返すことに動的に推定し続けることができます

# 参考文献

http://www.thothchildren.com/chapter/5c7bc083ba4d5d6b2c2419ea

http://lab.cntl.kyutech.ac.jp/~nishida/lecture/psc/no11.pdf
AntropicのFunction Callingを試してみた(まだ繋がらない。。）

AnthropicがFunctionCallingをBeta版として公開したので試してみた
https://docs.anthropic.com/claude/docs/tool-use
<br>

```
import anthropic

client = anthropic.Anthropic()

response = client.beta.tools.messages.create(
    model="claude-3-opus-20240229",
    max_tokens=1024,
    tools=[
        {
            "name": "get_location",
            "description": "Get the current user location based on their IP address. This tool has no parameters or arguments.",
            "input_schema": {
                "type": "object",
                "properties": {}
            }
        },
        {
            "name": "get_weather",
            "description": "Get the current weather in a given location",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "The city and state, e.g. San Francisco, CA"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "The unit of temperature, either 'celsius' or 'fahrenheit'"
                    }
                },
                "required": ["location"]
            }
        }
    ],
    messages=[{
   		  "role": "user",
    	  "content": "What's the weather like where I am?"
    }]
)

print(response)
```
API_KEYを環境変数に設定しておく（ご自身のKEYをおつかいください）
```
export ANTHROPIC_API_KEY=sk-ant-api03-XXXXXX
```

が、結果。。

```
anthropic.InternalServerError: Error code: 529 - 
{'type': 'error', 'error': {'type': 'overloaded_error', 'message': 'Overloaded'}}
```

<br>
みんな使いまくっているの繋がらないー

繋がったら続きを書く。。
Emmetを使って爆速でHTMLを書いてみよう！

# はじめに

Emmet(エメット)とは、EnterキーやTabキーを押すだけで自動変換され記述できる便利な機能です。

今回はよく使う基本的なもののご紹介です。

`<div>`とかいちいち手打ちするのは今日で終わりにしましょう！

:::note info
VSCodeはデフォルトでEmmetを利用できます
:::



# タグ
```
 div
```
と書いてEnter押すだけ
```
 <div></div>
```
開始タグと終了タグが挿入されます。


# クラス名付きのタグ
 ```
div.apple
 ```
と書いてEnter押したら
 ```
<div class="apple"></div>
 ```
`タグ.クラス名`でクラス名付きの要素を展開できます。



# idもいけるよ
 ```
header#orange
 ```
と書けば
 ```
<header id="orange"></header>
 ```
ちなみに、タグを省略した場合はdivタグが自動的に付与されるので、
```
 .apple
 #orange
```
で
```
<div class="apple"></div>
<div id="orange"></div>
```
クラスやidつきのdivタグがすぐ出せちゃいます。



# 兄弟要素を展開したい時は
 ```
div+p
 ```
と書けば
 ```
 <div></div>
<p></p>
 ```
`+`で兄弟要素を展開することができます。

# リストたくさん書く時めんどうな時は
 ```
 li*10
```
と書いて
 ```
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
<li></li>
 ```
`「*数字」`で繰り返しできます。


# ネストさせたい時は
 ```
 ul>li
  ```
と書けば
 ```
 <ul>
<li></li>
</ul>
 ```
 `「要素>要素」`でネスト構造の要素を展開できます。
 

# テーブル要素もあっという間に
 ```
 table>tbody>(tr>th+td)*3 
 ```
と書けば
 ```
<table>
  <tbody>
    <tr>
      <th></th>
      <td></td>
    </tr>
    <tr>
      <th></th>
      <td></td>
    </tr>
    <tr>
      <th></th>
      <td></td>
    </tr>
  </tbody>
</table>
 ```
`()`を使うことでグループを作れます。

# コメントアウトしたい時は
```
テスト
```

コメントアウトしたい文字を選択して、
```
{/* テスト */}
```
`Ctrl` +`/`を押すとコメントアウトできます。

# まとめ
今回は、VSCodeでHTMLをEmmetで記述する基本的な方法をご紹介しました。

エメット記法を覚えてしまうとコーディングがすごく早くなりますので、ぜひ試してみてください！

# 最後に

私の働いている会社で、経験の有無を問わず採用を行っています。
興味のある方は是非カジュアル面談から応募してみてください！

https://jambo-support.com/recruit_engineer/
MatlabからPython関数を呼び出す

# 目標：MatlabからPythonの関数を呼び出せるようにする

### はじめに
+ 本稿は自分自身の覚書として作成した
+ 本文中の各サイトを参考にしながら、一連の流れがわかるように手順を残す
+ 各サイトから有力な情報を得られました。大変感謝です


### 手順
1\. Pythonをインストール
2\. 外部パッケージをインストール
3\. Matlabから外部パッケージをインポート
4\. Matlabでパッケージを呼び出し、テスト実行

### 動作環境
| 項目 | 条件 |
|:-:|:-:|
| OS  | windows10 64 bit  |
|Matlab|version 2024a|
|Python|version 3.11|


# 1. Pythonをインストール
+ MatlabのバージョンにあったPythonをダウンロードする(下記リンク参照)
 https://jp.mathworks.com/support/requirements/python-compatibility.html

 下記の参考リンクをもとに、Python仮想環境を構築する
+ ダウンロードが終わったら、Pythonをインストールする
+ コマンドプロンプトで下記コマンドを実行し、仮想環境を構築する
```python:コマンドプロンプト
cd (保存したい場所)
python -m venv (仮想環境を保存するフォルダの名前) # 仮想環境を構築
```
参考リンク： https://campkougaku.com/2022/12/29/spyder_in_nonanaconda/



# 2. 外部パッケージをインストール
+ 1章で構築した仮想環境に、外部パッケージをインストールする
+ コマンドプロンプトで下記コマンドを実行

```python:コマンドプロンプト
% 仮想環境の呼び出し
cd (仮想環境を構築したフォルダの場所)
Scripts\activate.bat

# 仮想環境へ外部パッケージをインストール
pip install --upgrade pip
pip install numpy          # インストールしたいパッケージ名を入力
pip install opencv-python  # インストールしたいパッケージ名を入力
pip install matplotlib     # インストールしたいパッケージ名を入力
```

# 3. Matlabから外部パッケージをインポート
+ Matlabを実行
+ Matlabが自動でPythonのインタープリターを検出するが、自分で作った仮想環境を指定する必要があるので、下記コマンドを実行

```matlab:matlab
% pythonインタープリタの設定
pyenv
% 上記コマンドでVersion情報に違いがあれば、下記コマンドで正しい場所を設定
pyenv("Version", "(仮想環境の保存場所)\Scripts\python.EXE");

```
+ 下記コマンドでPython関数を実行し、動作チェック
+ エラーがなければ設定完了

```matlab:matlab
% Python関数の呼び出しテスト
py.list({'This','is a','list'});
myList = pyrun("l = ['A', 'new', 'list']", "l");
```

# 4. Matlabでパッケージを呼び出し、テスト実行
+ 以下の構文で外部パッケージをMatlab上に呼び出せる　※このとき、パッケージは事前に、2章で説明した方法に従い、インストールすること

```matlab:matlab
% 外部パッケージのインポート
np  = py.importlib.import_module('numpy');
cv  = py.importlib.import_module('cv2');
plt = py.importlib.import_module('matplotlib.pyplot');
```

+ 外部パッケージのテスト実行を行う
```matlab:matlab
% 外部パッケージのテスト実行
% cv2 を import して、imread する
cv = py.importlib.import_module('cv2');
array = cv.imread("(フルパス)\images.jpg"); 

% ndarray型をmatlabデータ型に変換
img = uint8(array);
imshow(img);
```
CSSの再利用性を高める！Mixinの基本

CSSの管理と保守は、大きなプロジェクトでは特に頭を悩ませることが多いです。そんな時に役立つのが、Sassの強力な機能「Mixin」です。この記事では、Mixinの基本から、効果的な使い方までを紹介します。

### Mixinとは？

Mixinは、CSSの宣言ブロックを再利用可能にするSassの機能です。複数の場所で使用されるCSSプロパティを一箇所にまとめ、コードの重複を避けることができます。また、引数を渡すことで、さらに柔軟にスタイルを適用することが可能になります。

### Mixinの定義と使用方法

Mixinを作成するには、`@mixin`ディレクティブを使用し、使用する際には`@include`ディレクティブを使用します。例えば、次のように定義して使用することができます。

```
@mixin second-color {
  color: blue;
}

.container {
  @include second-color;
}
```

引数無しでも、()を省略してMixinを定義・使用することができます。

### 引数の渡し方

Mixinはより汎用性を持たせるために、引数を受け取ることができます。キーを指定して引数を渡すことで、コードの可読性を高めることが推奨されます。

```
@mixin second-color($color: blue) {
  color: $color;
}

.container {
  @include second-color($color: yellow);
}
```

複数の引数を渡すこともできます。この機能を使うと、より複雑なスタイルも簡単に適用することが可能です。

### 引数に初期値を設定

引数には初期値を設定することも可能です。これにより、引数を省略した場合のデフォルトのスタイルを定義できます。

```
@mixin second-color($color: blue, $fontWeight: normal) {
  color: $color;
  font-weight: $fontWeight;
}

.container {
  @include second-color($color: yellow, $fontWeight: bold);
}
```

### まとめ

MixinはSassを使う上で非常に便利な機能です。CSSの再利用性を高め、コードの保守性を向上させることができます。引数を活用することで、さらに柔軟性を持たせることができるので、ぜひ活用してみてください。
ChatGPTでKustoクエリ―も生成する

# はじめに

プログラムも、IaCも、そしてKQLも、できることなら可能な限り生成AIに作ってもらいたいですよね。基本的なKQLの文法はGPTモデルに含まれているため、今回はKQL生成のちょっとしたTipsの紹介です。
なお、利用したモデルはGPT-4-Turbo(0125)です。

**※いずれCopilot for Azureでもできるようになっちゃうんだろうなぁとは思いますが、細かい調整とかしたいケースは今後もあると信じて**

# システムプロンプト

分析したい対象のテーブルの情報、ならびに特筆すべき情報を加えます。なお、以下はApplication Insight経由で、tracesとrequestsテーブル、かつtracesテーブルには独自ログをJSONフォーマットでいれている例です。Log Analyticsの場合、また分析したいテーブルに合わせて適宜変えてください。特に複数テーブルを結合して～とかの要望がなければ、テーブル情報は１つだけで大丈夫です。

```:システムプロンプト
あなたは Azure Application Insgiht のKQLマスターです。\
以下のテーブルについてユーザからの要望を満たすKQLクエリ―を作成してください。

**補足や説明は不要です。**
**KQLクエリ―のみ回答して下さい**

テーブル名: traces
列情報:
timestamp (datetime)
message (string)
severityLevel (int)
itemType (string)
customDimensions (dynamic)
(※長いので、省略します。全部記載してください。)

なお、列”message”の中に以下の5パターンのjsonが含まれています。
1. リクエスト
{
  "type": "input_message", 
  "message": "＜ユーザ入力の文章＞", 
  "token": "トークン数※"
}
(※2~4は冗長なので省略します。）

テーブル名: requests
列情報:
timestamp (datetime)
id (string)
source (string)
(※長いので、略)

```

これだけです。

# 試してみる

上記のシステムプロンプトを用意した上で、以下ようなユーザプロンプトを入力させます。

```:ユーザプロンプト
ユーザリクエストの入力文章を一覧化して
```

```:GPTの回答
　```kql
traces
| extend messageJson = parse_json(message)
| where messageJson.type == "input_message"
| project timestamp, UserInput=messageJson.message
　```
```

いい感じです。ちょっと複雑なやつも問題なく動きます。

```:ユーザプロンプト
requestsテーブルのnameに /getadvicewsを含むデータのdurationと、\
同じoperation_Id をもつtracesテーブルのmessageから\
pararell_inputのtokenを一覧化してください。
なお、tokenで昇順にソートしてください。

**tokenは空の場合はその行はデータとして出力しないでください。**
```

```:GPTの回答
　```kql
requests
| where name contains "/getadvicews"
| project operation_Id, duration
| join kind=inner (
    traces
    | extend messageJson = parse_json(message)
    | where messageJson.type == "pararell_input" and messageJson.token != ""
    | project operation_Id, token = tostring(messageJson.token)
) on operation_Id
| project duration, token
| order by token asc
　```
```

順番とか、場合によっては内容をちょっと変えたほうがいいkqlが生成されたりとかいくつかありましたが、おおむね80~90点以上のKQLは生成できているかと思います。(私が素で書くと落第します)

# まとめ

この記事では、ChatGPTを使ってKQLクエリを生成する方法について紹介しました。生成AIを使うことで、複雑なクエリも効率的に生成できる感触をつかんでいただけたらなら幸いです。ただ精度はそれなりに高いものの、微修正が必要なケースはあったので、やはりKQLに関する基礎的な理解は不可欠ですね…このあたりはモデルが進化してもやりたいことを伝えるためにも変わらず必要になりそうですね
EC2 AMIとEBSのバックアップをライフサイクルマネージャで取得する方法

# 概要
EC2のAMIとEBSスナップショットをライフサイクルマネージャで取得する方法をまとめる。

## 前提
EC2が作成されていること。

# 目次
- AMIバックアップ取得
- EBSバックアップ取得

# AMIバックアップ取得
1.マネジメントコンソールで[EC2]のコンソール画面を開き、[ライフサイクルマネージャー]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/32947935-5076-58c2-cd56-dcf786133106.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/3d5b97a6-e5e7-75c4-342b-e00b5ea94506.png)


2.以下の通りに入力して、[次へ]をクリックする。

・カスタムポリシーとデフォルトポリシーのどちらを使用するか選択します：カスタムポリシー
・スケジュールベースのポリシー：EBS-backed AMIポリシー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/ed0d5563-c608-553d-e836-0d16505be772.png)

3.以下の通りに入力して、[次へ]をクリックする。
・ターゲットリソースタグ：任意のキーと値を入力し、[追加]をクリック
・説明：任意の説明
・IAMロール：要件に合わせて選択
・ポリシーのステータス：有効
・インスタンスの再起動：要件に合わせて選択

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/e08d9d2a-3ad1-d88e-4dbe-c8964bbd11f3.png)

4.[スケジュールの詳細]を要件にあわせて作成し、[ポリシーを確認]をクリック。例ではデフォルト値に加えて、クロスリージョンコピーで大阪にコピー転送設定。



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/7d7cdb5b-9b37-6ff3-d6b2-d1b289f1cc33.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/5749ae42-1c45-879d-b8f8-60f3484519b1.png)



5.設定内容を確認し、[ポリシーを作成]をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/5c40dcbe-e61b-1acd-edf8-a0caba0cc1c2.png)


# EBSバックアップ取得


1.マネジメントコンソールで[EC2]のコンソール画面を開き、[ライフサイクルマネージャー]をクリックする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/32947935-5076-58c2-cd56-dcf786133106.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/3d5b97a6-e5e7-75c4-342b-e00b5ea94506.png)


2.以下の通りに入力して、[次へ]をクリックする。

・カスタムポリシーとデフォルトポリシーのどちらを使用するか選択します：カスタムポリシー
・スケジュールベースのポリシー：EBSスナップショットポリシー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/fdb1d7bf-ac00-91c1-9950-847777e7b874.png)


3.以下の通りに入力して、[次へ]をクリックする。
・ターゲットリソースタグ：任意のキーと値を入力し、[追加]をクリック
・説明：任意の説明
・IAMロール：要件に合わせて選択
・ポリシーのステータス：有効

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/96e7ca2e-d81e-46ed-4f7d-0acb1615862f.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/5c27404f-9f49-4508-dd34-1954f17c66b7.png)

4.[スケジュールの詳細]を要件にあわせて作成し、[ポリシーを確認]をクリック。例ではデフォルト値に加えて、クロスリージョンコピーで大阪にコピー転送設定。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/2d0b8b8f-5bb9-f722-d0c8-281a39291f74.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/e9a6f7c9-fb77-f642-afbc-961e492cc273.png)

5.設定内容を確認し、[ポリシーを作成]をクリックする。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3682297/4cee27b7-9676-c7fd-7544-ed16fce0386b.png)


■参考
▼AMI取得

https://docs.aws.amazon.com/ja_jp/ebs/latest/userguide/ami-policy.html


▼EBS取得

https://docs.aws.amazon.com/ja_jp/ebs/latest/userguide/snapshot-ami-policy.html
スクリプト言語(Python/js)で試すPQC（Post Quantum Cryptography）

去る2023年はPQC（Post Quantum Cryptography）がちょっとしたブームになった頃合いでした。
そして、今年2024年、そろそろ正式にPQCが制定される見込みとなっています

が、残念ながら、既存のRSA/ECCほど技術記事が豊富ではありません
当然、それにはいくつか理由があるのだとは思いますが、一つ挙げるとすれば、（再帰っぽいですが）技術記事が少ないから、ではないのかと

この現状に一石を投じるべく、これからいくつかの記事に分けて投稿していきたいと思います
なお、当然ですが、手を動かす関係上、実装を扱うことになりますが、ここはスクリプト言語で一歩づつ確認できればと思っています

トピックは順不同で、以下のようなものを考えています
（実装そのものを追いかける（PQCの基礎理論を追求する）ことは目的としておりません
現時点で存在する既存の実装をスクリプト言語(Python/js)で使用して、RSA/ECCと同様なことがどのようにできるかなどの確認が目的です）

### PQCの実装にはどんなものがある？

### PQCの実装を使ってみる(Python)

### PQCの実装を使ってみる(js)

### PQC鍵のサイズが合致しない？

### PQC署名と相互運用性の確認

### PQC証明書の生成

### KEMってなんだ？（KEXと違うの？）

### PQC対応Chromeの動作確認

### PQC対応Nginxのbuild
【Next.js】備忘録：pageルートでURLにIDをいれる


# はじめに

こんにちは、エンジニアのkeitaMaxです。

Next.jsで開発を行っている時に調べたことなどを記録しておきます。

# 作りたいもの

会議の一覧を以下のURL
```
http://localhost:3000/conferences/
```
会議で行うLTの一覧を以下のURL
```
http://localhost:3000/conferences/1/lightning-talks/
```
LTに対してのコメントの一覧を以下のURL
```
http://localhost:3000/conferences/1/lightning-talks/2/comments
```

以上のようなものを作成したいと思い調べました。


# やり方

>動的なセグメントにマッチさせたければブラケット記法を使うことができます。名前をつけたパラメータとのマッチが可能です。
(引用：https://nextjs-ja-translation-docs.vercel.app/docs/routing/introduction)

上に書いてあるように、以下のようにフォルダを作成しました。

```
pages/
 └ conferences/
    　├ index.tsx
    　└ [conference-id]/lightning-talks/
                        　├ index.tsx
                        　└ [lightning-talk-id]/comments/
                                                　└ index.tsx
```

`[conference-id]`に会議のIDを、`[lightning-talk-id]`にLTのIDを入れるようにしました。


# ページ遷移

>Next.js のルーターは、シングルページアプリケーションのようにクライアントサイドでのページ間遷移が可能です。
(引用：https://nextjs-ja-translation-docs.vercel.app/docs/routing/introduction)

ページ遷移をするには以下のようにするとできるそうです。

```tsx
<Link href="/conferences/1/lightning-talks/">
  <a>LT一覧ページへ</a>
</Link>
```


# おわりに

この記事での質問や、間違っている、もっといい方法があるといったご意見などありましたらご指摘していただけると幸いです。

最後まで読んでいただきありがとうございました！

# 参考

https://nextjs-ja-translation-docs.vercel.app/docs/routing/dynamic-routes