OmniAICreator/Qiita-1.07M huggingface dataset:
chatgptとGASを連携してスプシに回答を出力する

## 完成イメージ
C2に日本銀行の会見の文字起こしが入力されています。
GASを使いchatgptに要約してもらいそれをD2に出力しました。
![スクリーンショット 2024-07-14 23.59.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/398994/8295e500-b2d9-a63b-c6f3-386d3eab11d0.png)
## GASコード
```
function createArticle() {
  const secretKey = 'APIを入力してください';
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
  const articlePart = sheet.getRange('C2').getValue();
  
  const prompt = `以下の文章を使って要約してください。. Text: "${articlePart}"`;
  
  const apiUrl = 'https://api.openai.com/v1/chat/completions';
  const payload = {
    model: 'gpt-3.5-turbo',
    messages: [
      {role: 'system', content: 'You are a helpful assistant.'},
      {role: 'user', content: prompt}
    ],
    max_tokens: 500
  };

  const options = {
    method: 'post',
    contentType: 'application/json',
    headers: {
      'Authorization': 'Bearer ' + secretKey
    },
    payload: JSON.stringify(payload)
  };

  const apiResponse = UrlFetchApp.fetch(apiUrl, options);
  const responseText = JSON.parse(apiResponse.getContentText());
  const article = responseText.choices[0].message.content.trim();

  sheet.getRange('D2').setValue(article);
}

```

### シークレットキーの定義
```
const secretKey = 'APIキーを入力してください';
```
OpenAI APIを呼び出すためのシークレットキーを定義しています。このキーは認証に使用されます。
### スプレッドシートの取得
```
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('シート1');
```
スプレッドシートから名前が「シート1」のシートを取得しています。
### 記事の部分の取得
```
const articlePart = sheet.getRange('C2').getValue();
```
B2セルの値を取得しています。
### プロンプトの作成
```
  const prompt = `以下の文章を使って要約してください。. Text: "${articlePart}"`;
```
OpenAI APIに送信するプロンプトを作成しています。このプロンプトには取得した記事の一部とリンクが含まれています。
### APIリクエストのペイロード
```
const apiUrl = 'https://api.openai.com/v1/chat/completions';
const payload = {
  model: 'gpt-3.5-turbo',
  messages: [
    {role: 'system', content: 'You are a helpful assistant.'},
    {role: 'user', content: prompt}
  ],
  max_tokens: 500
};
```
APIのエンドポイントURLとリクエストペイロードを設定しています。ペイロードにはモデル、メッセージ、トークン数の制限が含まれています。
### APIリクエストのオプション設定
```
const options = {
  method: 'post',
  contentType: 'application/json',
  headers: {
    'Authorization': 'Bearer ' + secretKey
  },
  payload: JSON.stringify(payload)
};
```
APIリクエストのメソッド、コンテンツタイプ、ヘッダー、ペイロードを含むオプションを設定しています。ヘッダーには認証用のシークレットキーが含まれています。
### APIリクエストの送信とレスポンスの処理
```
const apiResponse = UrlFetchApp.fetch(apiUrl, options);
const responseText = JSON.parse(apiResponse.getContentText());
const article = responseText.choices[0].message.content.trim();
```
APIリクエストを送信し、レスポンスを取得しています。レスポンスのテキストをJSON形式でパースし、生成された記事の内容を取得しています。
### 生成された記事のスプレッドシートへの書き込み
```
sheet.getRange('D2').setValue(article);
```
取得した記事をD2セルに書き込んでいます。

### 最後に
今回はchatgptとGASを使い日銀の会見の文字起こしを要約してスプシに出力しました。

今後も経済や金融関係の発信をしていきますのでよろしくおねがいします。
【Eclipse】動的Webプロジェクトのディレクトリ構成を覚える

Javaでサーブレット/JSPを使ってWebアプリケーションを制作するにあたって、Eclipseの動的Webプロジェクトのディレクトリ構成を覚えるための自分用メモです。

# 使用環境
PC：MacBook Air 2018
OS：macOS Sonoma 14.3.1
IDE：Eclipse 2023
Webコンテナ：Tomcat 10.1.18

# サーブレット/JSPとは？
サーブレット（Java Servlet）とは、サーバー側で動的なWebページを生成・データ処理ができるJavaで記述されたプログラムです。
JSPは、サーブレットを自動で生成することができるファイルで、HTML内にJavaのプログラムを記述できます。

MVCモデルにおいて、サーブレットがController、JSPがViewを担当することによって、プログラマーとデザイナーが分担して作業できます。

## Eclipseで動的Webプロジェクトを作成
Eclipseでサーブレット/JSPを作成する場合、「ファイル」→「新規」→「プロジェクト」→「Web」→「動的Webプロジェクト」で動的Webプロジェクトを新規作成します。
（パッケージ・エクスプローラーを見ると、プロジェクトのルートにTomcatのサーバー・ランタイムが追加されています。）

ローカルリポジトリのルートディレクトリに作成する場合は、「デフォルト・ロケーションを使用」のチェックを外して、ロケーションにローカルリポジトリのルートディレクトリを指定して作成します。

あとは、Webモジュールの画面で「web.xmlデプロイメント記述子の生成」にチェックを入れて「完了」から作成を完了すればOKです。

## 動的Webプロジェクトのディレクトリ構成
まず、通常のJavaプロジェクトのディレクトリ構成は以下のようになります（ローカルリポジトリのルートディレクトリに作成した場合）。
```
. プロジェクトのルートディレクトリ
├── bin（クラスファイルを管理）
├── .classpath（隠しファイル）
├── .gitignore（隠しファイル）
├── .project（隠しファイル）
├── README.md
├── .settings（隠しフォルダ）
└── src
    └── パッケージ名
        └── Sample.java
```
それに対して、動的Webプロジェクトのディレクトリ構成は以下のようになります（ローカルリポジトリのルートディレクトリに作成した場合）。
```
. プロジェクトのルートディレクトリ
├── build
│   └── classes（クラスファイルを管理）
├── .classpath（隠しファイル）
├── .gitignore（隠しファイル）
├── .project（隠しファイル）
├── README.md
├── .settings（隠しフォルダ）
└── src
    └── main
        ├── java（src/main/java）
        │   ├── servlet
        │   │   └── IndexServlet.java
        │   └── model
        │       └── Sample.java
        └── webapp
            ├── META-INF
            │   └── MANIFEST.MF
            └── WEB-INF
                ├── jsp
                │   └── index.jsp
                ├── lib（ライブラリフォルダ）
                └── web.xml
```
WEB-INFディレクトリ以下はブラウザから直接リクエストできないので、jspファイルはWEB-INF以下にフォルダ（上記だとjspフォルダ）を作って管理しました。
コンピュータは2進数なので小数点に要注意

まずは以下のプログラムを作ります。
```Python3
a = 0
while a <= 10:
    print("%d"%a)
    a = a + 1
print()    
b = 0.0
while b <= 1.0:
    print("%f"%b)
    b = b + 0.1
print()
c = 0.0
while c <= 1.0:
    print("%.20f"%c)
    c = c + 0.1
print()
```
するとこのように出力されます。
```
0
1
2
3
4
5
6
7
8
9
10

0.000000
0.100000
0.200000
0.300000
0.400000
0.500000
0.600000
0.700000
0.800000
0.900000
1.000000

0.00000000000000000000
0.10000000000000000555
0.20000000000000001110
0.30000000000000004441
0.40000000000000002220
0.50000000000000000000
0.59999999999999997780
0.69999999999999995559
0.79999999999999993339
0.89999999999999991118
0.99999999999999988898
```
普通に「%f」で出力すると0~1になっているように見えていますが、小数点以下20桁を出力するとそうならないことが分かります。
それもそのはずで、コンピュータは2進数、つまり「ON」と「OFF」です。
そうなると整数は問題ありませんが、小数点は表現できません。
例えばこれは10進数でも言えることで、「1÷3」は「0.3333…」となりますが、これが3進数だったら3の-1乗なので0.1になります。なので3進数ですから0.1+0.1+0.1=1となります。
で、2進数の話に戻りますが、2進数の小数点の表現は0.5、0.25、0.125…となっており、これらから表現しないといけませんので10進数を前提とした計算は難しいということが分かります。
そのため20桁で表現した結果、このようになります。
データサイエンスの世界でも教授から「桁数指定して精度をフルに出さなくてもええんやで」というお話がありましたが、この話を知れば納得すると思います。
という、タグでも書きましたが駆け出しエンジニアに伝えたい豆知識でした。
ちなみにですが、2進数の数値ならしっかり表現できます。
```Python3
print("%.20f"%(0.5))
print("%.20f"%(0.25))
print("%.20f"%(0.125))
print("%.20f"%(0.0625))
print("%.20f"%(0.03125))
print("%.20f"%(0.015625))
```
```
0.50000000000000000000
0.25000000000000000000
0.12500000000000000000
0.06250000000000000000
0.03125000000000000000
0.01562500000000000000
```
# まとめ
10進数のコンピュータできないかなｗ
DeepL API翻訳をPythonから使ってみた

# 概要
DeepL翻訳はDeep Learningを用いた高い翻訳性能で知られています。APIも用意されており、様々な言語から利用可能です。よって、試みにPythonから実行してみることにしました。

# アカウント登録
DeepLのアカウント登録とは別にAPIのアカウント登録も行います。まずは**無料版**で利用を開始することにします。**無料で登録する**をクリックし、アカウント登録を行います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/b2ffe8f3-bd12-d8fd-4b56-90f69ad74cba.png)

# APIキーの取得
DeepL API翻訳を利用するにはAPIキーが必要です。以下のサイトの方法に則ってAPIキーを取得します。

https://support.deepl.com/hc/ja/articles/360020695820-DeepL-API%E7%94%A8%E3%81%AEAPI%E3%82%AD%E3%83%BC#h_01HM9MFQ195GTHM93RRY63M18W

# 環境情報
* Python 3.10.7
* deepl 1.18.0
* python-dotenv 1.0.1

# ライブラリのインストール
必要なライブラリをインストールします。

```bash
pip install deepl python-dotenv
```

# .envファイルを作成
開発を行うディレクトリ上で`.env`ファイルを作成して以下の内容を書き込みます。(<API_KEY>の部分は取得したAPIキーです。)

```bash
DEEPL_AUTH_KEY=<API_KEY>
```

# テストコードの実行
以下のコードを実行しました。

```python
import os

from deepl import Translator
from dotenv import load_dotenv

load_dotenv()

auth_key = os.getenv('DEEPL_AUTH_KEY')
# print(auth_key)

translator = Translator(auth_key)

result = translator.translate_text('Hello, world!', target_lang='JA')
print(result.text)
```

## 実行結果
正しく翻訳が出来ました！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469079/e6aa6303-1ab8-dfaf-4998-40c591180da6.png)

# まとめ
DeepL API翻訳を用いると簡単に翻訳出来ることが出来ました。pypdfと連携して便利ツールを実装したいと思います。

# Reference
https://github.com/theskumar/python-dotenv

https://note.nkmk.me/python-os-environ-getenv/

https://github.com/DeepLcom/deepl-python

https://developers.deepl.com/docs/resources/supported-languages#target-languages
【Rocky8】Nginx1.26.1にバージョンアップ

# 背景
RockyLinuxの8.10でnginxをインストールすると1.14.1がインストールされた
このバージョンは古いので新しいバージョンを入れるようにしてみます

# 環境
Ubuntu 22.04.4 LTS
Docker 27.0.2
rockylinux:8.10
nginx:1.26.1


# 手順
## docker準備
Rocky Linux 8.10のイメージを取得します
```
$ docker pull rockylinux:8.10
```
取得できたか確認
```
$ docker images
rockylinux                      8.10                 c79048e50f5f   7 months ago    198MB
```
コンテナを作成してみる
```
$ docker run -it -d --privileged --name R-Proxy -h R-Proxy -p 9080:80 -p 9443:443 rockylinux:8.10 /sbin/init
```
:::note warn
`/sbin/init`がないと`systemctl`が使えない
:::


## 開発
```
$ docker exec -it <コンテナID> /bin/bash
```
パッケージのインストール
```
# dnf update -y
# dnf install -y iproute wget gcc pcre pcre-devel zlib zlib-devel openssl openssl-devel make
```
Nginxのバージョンを上げます
```
# cd /tmp/
# wget http://nginx.org/download/nginx-1.26.1.tar.gz
# cd nginx-1.26.1.tar.gz
# ./configure --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --with-pcre-jit --with-http_addition_module --with-http_dav_module --with-http_gzip_static_module --with-http_realip_module --with-http_stub_status_module --with-http_ssl_module --with-http_sub_module --with-mail --with-mail_ssl_module
# make
# make install
```
インストール完了後の確認
```
# nginx -V
# systemctl start nginx
# systemctl status nginx
# systemctl enable nginx
```
:::note warn
エラー発生
`systemctl start nginx`にてFailが発生
```
Can't open PID file /run/nginx.pid (yet?) after start: No such file or director
```
`/etc/nginx/conf/nginx.conf`の中身を確認して、pidの指定がされているか確認
ない場合は以下を追加
```
pid        /run/nginx.pid;
```
:::
【React】選択中の文字列を取得する方法

画面上で選択中の文字列を取得するには[Selection API](https://developer.mozilla.org/ja/docs/Web/API/Selection_API)を使用します。

```tsx
import { useCallback, useEffect } from 'react'

export function Sample() {
  const handleSelectionChange = useCallback(() => {
    const selection = document.getSelection()
    console.log(selection?.toStoring()) // 選択されている文字列をコンソールに出力
  }, [])

  useEffect(() => {
    document.addEventListener('selectionchange', handleSelectionChange)

    return () => {
      document.removeEventListener('selectionchange', handleSelectionChange)
    }
  }, [handleSelectionChange])

  return (
    <p>
      サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。サンプルのテキスト。
    </p>
  )
}

```

https://developer.mozilla.org/ja/docs/Web/API/Document/getSelection

https://developer.mozilla.org/en-US/docs/Web/API/Selection/toString

https://developer.mozilla.org/ja/docs/Web/API/Document/selectionchange_event
投稿 14 環境変数  2024/07/14

本日の勉強時間　8H

.envファイルを作成して環境変数を分割する、リファクタリング作業があります。

書いていく前に必ず.gitignoreファイルを作成し、そこに「.env」を追記するのを忘れないように。
一応”やっちゃった”あとの対応が書かれてるので、それを参考にするといい。
https://qiita.com/fuwamaki/items/3ed021163e50beab7154
https://qiita.com/yutoun/items/7dfc61a8aa0ca94eda0d
varって存在価値あるの？

## 事の発端
ある日私はJavaScriptの歴史について少し学びました。
その中で、ES6(ECMAScript2015)でletとconstが追加され、varが非推奨になったことを知りました。
また、ある時には友人からvarは使うんじゃないと言われました。
そこで私は思いました。
**「なんでvarなんて存在するの！？varっていらない子じゃない！？」** と。

しかし、存在するからには何か理由があるのだろうと私はvarについて少し調べてみることにしました。

## JavaScriptにおけるvar
varはletやconstのようなJavaScriptには変数を宣言するためのキーワードです。
このvar, let, constのは以下の表に示すような違いがあります。
|          | var    | let      | const    |
| -------- | ------ | -------- | -------- |
| **再代入**  | 可能     | 可能       | 不可能      |
| **再宣言**  | 可能     | 不可能      | 不可能      |
| **スコープ** | 関数スコープ | ブロックスコープ | ブロックスコープ |
| **巻き上げ** | 起こる    | 起こらない    | 起こらない    |

## なぜJavaScriptを書く上でvarは嫌われているのか
上の表で示されているようにvarは再宣言が可能という特徴があります。
再宣言が可能なことで、気づかないうちに二重で宣言してしまい予期しない不具合が発生する危険性を孕んでいます。

例えば、以下のような訳のわからないことが発生します。
``` js
var num = 1;
console.log(num); // -> 1

if(num === 1) {
  var num = 1234;
  console.log(num); // -> 1234
}

console.log(num); // -> 1234
```

1. `var` を使用し、 `num` という変数を宣言
2. if 文の中で `var` を使用し、 `num` という変数を宣言している。 `let` や `const` であればブロックスコープの中で宣言したという扱いになり変数名は衝突しないが、 `var` にはブロックスコープがないため、変数名が衝突。再宣言が起きて1行目の `num` の中身が書き換わってしまう
3. `num` が 1234 になる
> 引用：[恐怖！ var の動きが意味不明すぎる！ #JavaScript - Qiita](https://qiita.com/kawayanagi/items/8037a736223d8fc790c1)

このようなことが発生するため、varは嫌われES6以降は使わないようにしましょうと言われているようです。

## JavaScript以外のプログラミング言語におけるvar
調べてみるとvarはJavaScript以外でも使われている言語があるようです。
しかし、どうやら仕様がそれぞれ異なるようです。
### JavaやC#,D言語
これらの言語でのvarは暗黙的に型を推論するために使用されるものです。
再宣言はできません。
変数の型が右辺から明らかな場合や型名が長い場合にvarを使うことでコードを読みやすくします。
例えば、以下のような場合です。
```java
// 従来の書き方 
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
```
```java
// varを使った書き方
var dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
```
>引用：[【Java】varを使うべき場合、使うべきではない場合 #型推論 - Qiita](https://qiita.com/dhirabayashi/items/a4a13d19b41779325bb0)
### Scala
Scalaには変数が再代入できるvarと再代入できないvalの2種類の変数があります。
再宣言はできません。

## なぜJavaScriptではvarが存在するのか
この部分に関してはあまり有用な記事を発見できず、自分の推測・妄想で書いているので詳しい先輩エンジニアの方がいらっしゃいましたら教えていただけると幸いです。
### なぜ開発当初にこの仕様のvarを実装し、他の変数を用意しなかったのか
JavaScriptは1995年にわずか10日間で開発されたようです。
そのため、実装しやすくするために再代入も可能なvarを実装したのかもしれないです。
### なぜ今もJavaScriptにvarは残っているのか
ES6以前に実装されたサイトやES6以降も慣れたvarで書いている人もいるため、varを消してしまうと様々なサイトで不具合が発生されると考えられるためだと私は考えます。

## さいごに
- JavaScriptにおいてvarは再宣言が可能な変数で、letやconstが存在する現在(ES6以降)では時代に置き去りにされた要らない子のようです。
- JavaScript以外では現役のようです。

## 参考にさせて頂いた記事
- [JavaScript - Wikipedia](https://ja.wikipedia.org/wiki/JavaScript)
- [JavaScriptにおけるvarとletの違い #TypeScript - Qiita](https://qiita.com/TechYoichiro/items/d538c4fa528d8878c8c9)
- [JavaScriptでvarが非推奨な理由を整理してみた #ECMAScript - Qiita](https://qiita.com/ist-t-s/items/49ed558bd837452353b8)
- [恐怖！ var の動きが意味不明すぎる！ #JavaScript - Qiita](https://qiita.com/kawayanagi/items/8037a736223d8fc790c1)
- [【Java】varを使うべき場合、使うべきではない場合 #型推論 - Qiita](https://qiita.com/dhirabayashi/items/a4a13d19b41779325bb0)
- [var（型推論）の利用指針について #C# - Qiita](https://qiita.com/Nossa/items/e5e50d2fc1ae8b3e2389)
- [Scalaの変数について #メモ - Qiita](https://qiita.com/chara06ken/items/fde41d1ce120812821cb)
AtCoder 勉強記録[C++] その20

AtCoderで入茶を目指して勉強しています。
勉強を継続するために投稿を始めました。
もともとアカウントを作成していましたが、今年の4月から本格的に勉強を始めました。
一応自分用に解法を書いていますが雑です、自分で読み返して困ったら修正します。
[私のアカウント](https://atcoder.jp/users/nanami_brother)
[解いた問題](https://kenkoooo.com/atcoder/#/table/nanami_brother)
# 本日解いた問題
## B - Practical Computing
[B - Practical Computing](https://atcoder.jp/contests/abc254/tasks/abc254_b)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  vector<vector<ll>> a(n, vector<ll>(0));
  ll cnt = 1;
  for(int i = 0; i < n; i++){
    for(int j = 0; j < cnt; j++){
      if(j == 0) a[i].push_back(1);
      else if(i == j) a[i].push_back(1);
      else {
        ll x = a[i-1][j-1] + a[i-1][j];
        a[i].push_back(x);
      }
      cout << a[i][j] << " ";
    }
    cout << endl;
    cnt++;
  }
}
```
### 解法
解答を入れる二次元配列`A`を用意する。`j=0`の場合に`A[i][j]`に1を入れて、`i=j`の場合に`A[i][j]`にも1を入れる。それ以外の場合に`A[i][j]`に`A[i-1][j-1]+A[i-1][j]`を入れることで解答が求まる。
## C - NewFolder(1)
[C - NewFolder(1)](https://atcoder.jp/contests/abc261/tasks/abc261_c)
解答
```c++
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vec = vector<ll>;
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

int main() {
  ll n;
  cin >> n;
  string s;
  map<string, ll> res;
  rep(i, n){
    cin >> s;
    if(res.count(s) != 0){
      res[s]++;
      cout << s << '(' << res[s] << ')' << endl;
    } else {
      res[s] = 0;
      cout << s << endl;
    }
  }
}
```
### 解法
解答のための`Map`を用意する。入力された文字列が0個の場合、そのまま文字列を出力し、`X`個の場合は文字列と`(X)`を出力する。
nginxのシンボリックファイルとは

# シンボリックリンクとは
シンボリックリンク（symbolic link）は、ファイルシステム上の特殊なタイプのファイルで、別のファイルやディレクトリへの参照を提供するもの。(シンボリックリンクは、別のファイルやディレクトリへのポインタやショートカットのようなもの。)


#### 作成コマンド
```
ln -s ターゲット リンク名
```

#### 作成例
```
sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/site1.conf
sudo ln -s /etc/nginx/sites-available/site1.conf /etc/nginx/sites-enabled/
```
## メリット
#### シンボリックリンクを使用する主な利点:
1. 柔軟性: サイトの有効/無効を簡単に切り替えられる
1. 安全性: 元のファイルを変更せずに設定を管理できる
1. 整理: 全ての設定と有効な設定を分けて管理できる
1. スケーラビリティ: 多数のサイトを効率的に管理可能


#### シンボリックリンクを使用しない場合
1. 設定ファイルをコピーする必要がある
1. ファイルの同期が難しくなる
1. 誤って元のファイルを編集してしまうリスクがある



### 全体図

```
sites-available/ (設定の倉庫)
    |
    +--- site1.conf (スイッチOFF)
    |
    +--- site2.conf (スイッチOFF)
    |
    +--- site3.conf (スイッチOFF)

sites-enabled/ (アクティブな設定)
    |
    +--- site1.conf -> ../sites-available/site1.conf (スイッチON)
    |
    +--- site2.conf -> ../sites-available/site2.conf (スイッチON)
```

#### 大規模環境のディレクトリ構造例
```
/etc/nginx/
│
├── nginx.conf
│
├── conf.d/
│   ├── global-settings.conf
│   ├── ssl-params.conf
│   └── ...
│
├── sites-available/
│   ├── site001.conf
│   ├── site002.conf
│   ├── site003.conf
│   │   ...
│   └── site100.conf
│
└── sites-enabled/
    ├── site001.conf -> ../sites-available/site001.conf
    ├── site002.conf -> ../sites-available/site002.conf
    ├── site003.conf -> ../sites-available/site003.conf
    │   ...
    └── site100.conf -> ../sites-available/site100.conf
```

結論:
Nginxにおけるシンボリックリンクの使用は、大規模なWebホスティング環境での設定管理を大幅に簡素化。これにより、管理者は迅速かつ安全にWebサイトの追加、削除、テスト、および維持を行うことが可能。
【React】フッターをいい感じに配置する

# はじめに
備忘録として残します。
もっと良い書き方があれば指摘していただけると幸いです。

ヘッダーはページ最上部、フッターはページ最下部に来るようにコンポーネントを作成していきます。

# コード

```LayoutWrapper.tsx
"use client";

import styled from "styled-components";

const LayoutWrapper = styled.div`
  width: 100%;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
`;

export default LayoutWrapper;
```

```Footer.tsx
"use client";

import styled from "styled-components";

const FooterComponent = styled.footer`
  margin-top: auto;
  padding: 15px 0;
  text-align: center;
  color: #fff;
  background: #000;
`;

const FooterText = styled.p`
  font-size: 16px;
`;

const Footer = () => {
  return (
    <FooterComponent>
      <FooterText>Sample Page Author: SBS_takumi</FooterText>
    </FooterComponent>
  );
};

export default Footer;
```

```layout.tsx
(中略)
<LayoutWrapper>
 <Header/>　// 任意のHeaderコンポーネントでよいです。
 {children}
 <Footer/>
</LayoutWrapper>
```

# 説明

LayoutWrapperについて、`min-height: 100%`にすることで、`children`の内容が少ない場合でも画面いっぱいに要素が表示されるようになります。

`display: flex`、`flex-direction: column`とすることで、LayoutWrapper内の要素が
列(縦)方向に並ぶようになります。
これを利用して、ヘッダー、フッター、childrenを縦方向に並べることができます。

上記の設定を行ったうえでFooterComponentについて、`margin-top: auto`と設定することでページ最下部にフッターを固定することができます。
神ExcelのためのVBA はがきの宛名を差し込み印刷

## 普段からExcelを酷使している会社ならみんなやってるはず

### Excelのみで差し込み印刷 はがき用
投稿マラソンの最後にふさわしく、神ってるExcelをさらに（？）便利にするためのコードを書きました。

WordでExcelのデータを引用して差し込み印刷する方法もありますが、頻繁に印刷する必要がある場合はそれも割と手間がかかります。Excelだけで完結出来たら便利ですね。

真の神Excelを名乗るなら、高度なセル結合とExcel方眼紙のテクニックを駆使して、差し込む文字列（宛名の住所、名前等）が入る欄をセルにするべきですが、めんどくさいのでテキストボックス（ユーザーフォームではない方）にしました。
テキストボックスなら、大きさを必要に応じて簡単に調整できるので、怠惰のレベルを上げたい方向きです。

一応、はがき用としていますが、テキストボックスの位置や大きさを調整すれば、封筒にも対応できます。

雑にA1セルのみでやっています。セルの大きさは適宜調整する必要があります。
印刷範囲をA1セルのみに指定して、用紙をはがきサイズで指定すれば、きれいにはまると思います。

「郵便番号」「住所」「名前」「敬称」は、すべて挿入タブからシートに入れたテキストボックスです。ここで入っている文字列がそのままテキストボックス名になっています。
![はがき実行前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/cbef9795-0c8a-03e4-2ce8-eae5a13b4884.png)

宛名リスト
![はがきリスト2png.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/b2d4e6b3-0790-462d-fb29-ac7f106e3f90.png)

コード
```vb
Sub InsertAddress()

  Dim i As Long
  Dim LastRow As Long
  LastRow = Sheets("リスト").Cells(Rows.Count, 1).End(xlUp).Row
  
  Dim ws As Worksheet
  Set ws = Sheets("はがき")
  Dim wsList As Worksheet
  Set wsList = Sheets("リスト")

  'リストからテキストボックスへ転記
  With ws.Shapes
  
    For i = 2 To LastRow
    
    .Range(Array("郵便番号")).TextFrame2.TextRange.Text = wsList.Cells(i, 2)
    .Range(Array("住所")).TextFrame2.TextRange.Text = wsList.Cells(i, 3)
    .Range(Array("名前")).TextFrame2.TextRange.Text = wsList.Cells(i, 4)
    .Range(Array("敬称")).TextFrame2.TextRange.Text = wsList.Cells(i, 5)
    
    'ws.PrintOut プリンターがある環境ではこの行をコメント解除
    '動作テスト
    Debug.Print ws.Shapes.Range(Array("名前")).TextFrame2.TextRange.Text
    
    Next i
    
  End With
  
  '初期化
  With ws.Shapes
    
    .Range(Array("郵便番号")).TextFrame2.TextRange.Text = "郵便番号"
    .Range(Array("住所")).TextFrame2.TextRange.Text = "住所"
    .Range(Array("名前")).TextFrame2.TextRange.Text = "名前"
    .Range(Array("敬称")).TextFrame2.TextRange.Text = "敬称"
    
  End With
  
End Sub
```

実行結果
![はがき実行結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/9a5fb243-4cc1-062e-708f-f2123f0f9b5f.png)

### なぜか動かなかった書き方
ws.Shapes.Range(Array("郵便番号")).TextFrame2.TextRange.Text でテキストボックスを指定していますが、ググったら違う書き方もでできました。

https://daitaideit.com/vba-shapes-text/

![動かない書き方.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3812230/71caa06a-6a9c-7fcd-3d4b-38890bf7dcfb.png)

最初はこれを読んで、
シート名.Shapes("テキストボックス名").TextFrame.Characters.Text = "文字列"
でテキストボックスに文字列が入ると思いましたが、プロシージャが全く動きませんでした。しかもステップインしようとしても動きませんでした。
Excelのバージョンは2021です。

↓動いた方の書き方
```vb
シート名.Shapes.Range(Array("郵便番号")).TextFrame2.TextRange.Text = "文字列"
```
ところで、TextFrame2 の「2」ってなんだろう
知っている人がいたら教えてください。

参考URL コードの書き方についてはこちら

https://www.relief.jp/docs/excel-vba-textframe2-textrange-characters-text.html

参考URL 神Excelについて

https://non-programmer.or.jp/blog/voicy-let-me-try-to-explain-about-god-excel-in-a-way-that-a-middle-school-student-can-understand/
TypeScript環境構築

# package.json作成
このファイル内でライブラリやwebpackの管理を行う
```zsh
npm init -y
```
![スクリーンショット 2024-07-14 22.55.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3648477/3983bbcc-e6ca-89db-101a-6096ac28a8d5.png)



# Node確認
インストールしていなければインストール
```zsh
node -v
```

# ローカルで使えるTypeScriptをインストール
```zsh
npm i -D
npm i --save-dev typescript
```

package.json内に以下の内容が表示される
```typescript
"devDependencies": {
    "typescript": "^5.5.3"
}
```
![スクリーンショット 2024-07-14 23.01.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3648477/e7f85b4d-7019-5ead-1c84-e22cd85a20ea.png)

# TypeScriptがインストールされたら
**tscコマンドが使える状態になっているかを確認**
```zsh
npx tsc -v
Version 5.5.3
```

node_modules/.bin内にtscが作成され,tscコマンドが使える状態になる
typescriptからjavascriptにコンパイリングするときなどに使用するコマンド


![スクリーンショット 2024-07-14 23.05.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3648477/0ddcdfff-1a8a-13dd-34d6-b8842e26c14c.png)
同じ要素をn回繰り返すイテレータ・文字列を作成したい

同じ要素をn回繰り返すイテレータを作成したい場合、`std::iter::repeat`を利用します。

```rust
let mut iter = std::iter::repeat('A').take(3);
assert_eq!(iter.next(), Some('A'));
assert_eq!(iter.next(), Some('A'));
assert_eq!(iter.next(), Some('A'));
assert_eq!(iter.next(), None);
```

同じ要素をn回繰り返す文字列については、`std::iter::repeat`を利用する必要はなく、`repeat`メソッドを利用すればよいです。

```rust
let s = "ABC".repeat(3);
assert_eq!(s, "ABCABCABC");
```

**環境情報**

```
$ rustc -V
rustc 1.75.0 (82e1608df 2023-12-21)
```
チームの絆を強化する！効果的なエンジニアコミュニケーション術

# はじめに
こんにちは！今回は、エンジニアチームのコミュニケーションについて触れていきたいと思います。
エンジニアとしてプロジェクトに携わるなかで、チームワークの重要性に考えることも多いのではないでしょうか。

<font color="Red">**実は、コミュニケーションのスキルは技術力と同じくらい大切です。**</font>

この記事では、エンジニアチームがどのようにして効果的なコミュニケーションを築けるのかを、最新の研究や実践的なアドバイスを交えながら詳しく解説していきます。

# 対象読者
- エンジニアチームを組織しているマネージャー
- チーム開発に携わるエンジニア
- プロジェクトマネージャー

# 目次
1. エンジニアチームのコミュニケーションの重要性
2. 効果的なコミュニケーションのためのベストプラクティス
3. 最新研究から学ぶエンジニアチームの成功例
4. 実際のお仕事に活かせるコミュニケーション術
5. まとめ

# 1. エンジニアチームのコミュニケーションの重要性
エンジニアチームのコミュニケーションが上手くいっていると、プロジェクトはスムーズに進行し、生産性が向上します。また、チームメンバー同士の信頼関係が強まり、問題解決も迅速に行えるようになります。

:::note info
**ポイント:** コミュニケーションが豊かなチームは、プロジェクトの成功率が高くなることが多いです。チーム内の情報伝達が確実であることが重要です。
:::

### 一致団結の力
エンジニアリングレベルの高いプロジェクトほど、各メンバーの専門知識や技能が求められます。そこで必要になるのが一致団結の力です。各自の役割を明確に把握し、どの情報が誰にとって重要かを理解しておくことが大切です。

### コミュニケーションの障害
しかし、実際にコミュニケーションにはさまざまな障害が存在します。例えば、リモートワークによる情報の伝達の遅れや、技術的な背景の違いによって生じる理解のズレなどがあります。

# 2. 効果的なコミュニケーションのためのベストプラクティス
ここからは、エンジニアチームが効果的にコミュニケーションを行うためのベストプラクティスをいくつか紹介します。

### 定期的なミーティング
定期的なミーティングは、全員が最新の情報を共有できる貴重な機会です。特にスプリントミーティングやデイリースタンドアップミーティングは効果的です。

:::note info
**ポイント:** ミーティングはなるべく短く、一貫性を持って行うことが重要です。Agendaを事前に共有し、時間を有効に使いましょう。
:::

### 透明性の確保
プロジェクトの進行状況や課題について、チーム全体で共有するようにしましょう。透明性があることで、問題が発生したときに迅速に対応できます。

### 技術とツールの活用
コミュニケーションツール（Slack, Teams, Trelloなど）を活用して、効率的な情報共有を図りましょう。特にドキュメントやタスク管理ツールを用いることで、情報の見える化が進みます。

# 3. 最新研究から学ぶエンジニアチームの成功例
最新の研究を参考に、成功しているエンジニアチームの共通点を見ていきましょう。以下のリンク先も是非参考にしてください！

### 研究事例：効果的なチームの特性
[Springer論文](https://link.springer.com/article/10.1007/s10664-021-10027-z)によると、成功しているチームの特性として、以下の点が挙げられています。
- 緊密なコミュニケーション
- 共有ビジョン
- 明確な役割分担

### フロントラインの心理学
[Frontiersin論文](https://www.frontiersin.org/journals/psychology/articles/10.3389/fpsyg.2020.569198/full)によれば、心理的安全性の確保がチームのパフォーマンスに大きな影響を与えます。メンバーが気軽に質問や提案をできる環境が、クリエイティビティを促進します。

:::note info
**ポイント:** 心理的安全性を高めるために、フィードバックをポジティブに受け入れる文化を築くことが大切です。
:::

### ハイパフォーマンスチームの実践
[CIPDのガイドライン](https://www.cipd.org/globalassets/media/knowledge/knowledge-hub/evidence-reviews/2023-pdfs/8388-high-performing-teams-practice-summary.pdf#:~:text=URL%3A%20https%3A%2F%2Fwww.cipd.org%2Fglobalassets%2Fmedia%2Fknowledge%2Fknowledge)によると、高性能なチームは以下の要素を重視しています。
- 継続的な学習と改善
- チームメンバーのエンゲージメント
- 効果的なリーダーシップ

# 4. 実際の仕事に活かせるコミュニケーション術
では、実際に職場で実践できるコミュニケーション術をいくつか紹介します。

### オープンドアポリシー
リーダーやマネージャーが「いつでも来てください」という姿勢を持つことで、メンバーが気軽に相談や意見交換ができる環境を作りましょう。

### コミュニケーションのトーンに気をつける
議論が白熱するときは特に、攻撃的な言葉遣いを避け、建設的な言葉を選ぶことが大切です。

### フォーマルとインフォーマルのバランス
フォーマルなミーティングだけでなく、インフォーマルな雑談やランチミーティングも大切にしましょう。これにより、よりリラックスした関係が築けます。


:::note info
**ポイント:** フォーマルとインフォーマルなコミュニケーションのバランスを取ることで、チーム全体の結束力が高まります。
:::


# まとめ
エンジニアチームのコミュニケーションはプロジェクトの成功に直結します。定期的なミーティング、透明性の確保、技術とツールの活用など、さまざまな方法でコミュニケーションを強化していきましょう。
また、最新の研究から学ぶことも大いに役立ちます。このブログを通じて、みなさんのチームがさらに強力になることを願っています！
Go言語のジェネリクス

## Go言語のジェネリクスの使い方とその利点
Go言語は静的型付けプログラミング言語であり、型安全性を保ちながら効率的なコードを書くことができます。Go 1.18で導入されたジェネリクスは、異なるデータ型に対して再利用可能な関数やデータ構造を作成するための強力な機能です。この記事では、ジェネリクスの基本的な使い方とその利点について説明します。
## ジェネリクスとは？
ジェネリクスは、さまざまなデータ型で動作する関数やデータ構造を作成するための機能です。これにより、特定のデータ型に依存しないコードを書くことができます。例えば、整数や浮動小数点数、文字列などを扱う関数を1つのジェネリック関数として定義できます。
## 基本的な使い方
ジェネリクスを使うには、型パラメータを関数や型に追加します。型パラメータは角括弧（[]）内に定義され、各パラメータは大文字で始まる識別子にします。
例1: 配列の要素の合計を計算する関数
以下の例では、整数と浮動小数点数の配列の合計を計算するジェネリック関数を定義しています。
```go:例
package main

import (
    "fmt"
)

// 型パラメータTを定義し、int型かfloat64型を受け付ける
func Sum[T int | float64](nums []T) T {
    var sum T
    for _, v := range nums {
        sum += v
    }
    return sum
}

func main() {
    ints := []int{1, 2, 3, 4, 5}
    floats := []float64{1.0, 2.0, 3.0, 4.0, 5.0}

    fmt.Println("Sum of ints:", Sum(ints))
    fmt.Println("Sum of floats:", Sum(floats))
}
```
```:結果
Sum of ints: 15
Sum of floats: 15
```

この例では、Sum関数は型パラメータTを持ち、int型かfloat64型を受け付けます。main関数では、整数と浮動小数点数のスライスを作成し、それぞれの合計を計算しています。
例2: 任意の型の配列を表示する関数
以下の例では、任意の型の配列を表示するジェネリック関数を定義しています。
```go:例
package main

import (
    "fmt"
)

// 型パラメータTを定義し、任意の型を受け付ける
func Display[T any](nums []T) {
    for _, v := range nums {
        fmt.Println(v)
    }
}

func main() {
    ints := []int{0, 1, 2}
    floats := []float64{10.0, 11.0, 12.0}
    strs := []string{"a", "b", "c"}

    Display(ints)
    Display(floats)
    Display(strs)
}
```
```:結果
0
1
2
10
11
12
a
b
c
```
この例では、Display関数は型パラメータTを持ち、任意の型を受け付けます。main関数では、整数、浮動小数点数、文字列のスライスを作成し、それぞれの要素を表示しています。
## ジェネリクスの利点
#### 1. 型安全性の向上
ジェネリクスを使用することで、型安全性を保ちながら汎用的な関数やデータ構造を作成できます。これにより、型アサーションや型キャストの必要がなくなり、ランタイムエラーのリスクが減少します。
#### 2. コードの再利用性の向上
ジェネリクスを使用することで、異なるデータ型に対して同じ関数やデータ構造を再利用できます。これにより、コードの重複を減らし、保守性が向上します。
#### 3. コードの簡潔化
ジェネリクスを使用することで、複数のデータ型に対応するために別々の関数を書く必要がなくなります。これにより、コードがより簡潔になり、読みやすくなります。
## まとめ
Go言語のジェネリクスは、型安全性を保ちながら効率的なコードを書くための強力な機能です。ジェネリクスを使用することで、異なるデータ型に対して再利用可能な関数やデータ構造を作成でき、コードの重複を減らし、保守性を向上させることができます。
組み込み向けにログを書き込むやり方を考えてみる

組み込み向けの用途に、例えばログファイルに、何回起動したかが書き込まれているとします。


runcount.log:
```
11
```


これを書き換えるにはどうしたらいいかな?


昔なつかし cgi だと、ファイルロックをつかって同時書き換えが起こらないようにしたりしました。

今回は、組み込みということで下記濃いプロセスは1つしかない前提で考えてみます。
その場合競合は発生しません。しかしながら書き換え中に電源断が発生したり、ログファイルを保存するデバイスが脆弱で、あまりあてにならないような状況を考えてみます。

# 環境

- python 3.10

# ファイルにカウントを書き込む

```
filename="upcount.log"
with open(filename, 'w') as f:
    print(upcounter, file=f)  
```

としたら、ファイルオープン中に電源が切れてしまうとファイル内容が失われてしまいますね。
テンポラリファイルに書き込みを行い、書き込みが終了したらログファイルにリネームするという方法が取れます。

```
inport os
filename="upcount.log"
backupfilename="upcount.log_bak"
tmpfilename="_upcount.log"
f = open(filename, "w")
print(upcounter, file=f)
f.close()
os.rename(filename,backupfilename) 
os.rename(tmpfilename,filename) 
  
```

ファイルシステム操作はキャッシュが入るのでリアルタイム性はありませんが、リネーム中に電源断になると "upcount.log" が存在しなくなる可能性があります。その場合は "upcount.log_bak" から復元すればいいのですが、 
```
os.rename(filename,backupfilename) 
```
の処理がうまく行かなかった場合は両方のファイルが失われる可能性があるのでは?


# アペンドモードで考える


```
filename="upcount.log"
with open(filename, 'a') as f:
```

として、

upcount.log には

```
1
2
3
4
5
6
7
8
9
10
```

とカウントが増えるように書き込みます。


そうなると書き込み途中で電源断になったりしても最新の情報が反映されないだけで一つ前の情報は残るのではないかな?


こういった場合のログからの情報の取り出しを以下のように書いてみました。
```
#!/usr/bin/env python3
filename = "upcount.log"

with open(filename, 'r') as f:
  lines = f.readlines()
logvalue=0
# 最後から正常な数字が見つかるまで1行ずつ評価  
for i in range(len(lines)-1, -1, -1):
  try:
    logvalue=int(lines[i])
    break
  except ValueError:
    continue
print(logvalue)
```


upcount.log の内容が以下のように化けてたりしても、
```
1
2
3
4
5
a6
7djkj8
9.31

11^B
```
最後の正常に見える値「5」を得ることができます。

なお、このログファイルにはカウント数字が書かれているだけだけど、いろんな情報を1行に載せているときは正規表現などでパースすれば良い。


# コード



```
#!/usr/bin/env python3
filename = "upcount.log"
upcounter=0

# 取り出し
f= open(filename, 'r')
lines = f.readlines()
f.close()
# 最後から正常な数字が見つかるまで1行ずつ評価  
for i in range(len(lines)-1, -1, -1):
  try:
    upcounter=(int(lines[i]))
    break
  except ValueError:
    continue
# 1を加えて書き込み
f= open(filename, 'a')
print(upcounter+1,file=f)
f.close()
```


明示的に close するために、with open ではなく f=open の構文を使っています。

# 欠点

log の肥大化の対策は行っていません。
RaspberryPi などに USB メモリを刺して、そこにログを書き込み、ユーザーが引っこ抜いて整備できるように考えています。そのような USB メモリだと数千行あっても特に問題は起こらないのではないかとの想定です。
【AWS】ECS on EC2とFarget構築時を比較して感じた注意点４つ

# 概要
今までAWS ECS on EC2を使っており、Fargateを使ったことがありませんでした。そこで、EC2で構築した際とFargateを利用した際を比較すると、Fargate構築時のみの注意点があると感じたので紹介します（特にCloudformationを利用して作成すると感じた点になります）。

## 注意点1：ネットワークモードは`awsvpc`

そもそもFargetはサーバーレスモデルなので、EC2ではなく、タスクにプライベートIPアドレス（正確にはENI）が割り当てられる形です。そのため、ネットワークモードは`awsvpc`のみをサポートする形になっています。

公式ドキュメントにも以下のように記載されています。

> Fargate 起動タイプを使用している場合、awsvpc ネットワークモードが必要です。
引用元：https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task_definition_parameters.html


ネットワークモードには他にも`bridge`や`host`があります。詳しくは公式ドキュメントご参照下さい。

https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-networking.html


## 注意点2:コンテナポートのみをマッピングする

`networkMode`が`awsvpc`の場合、ポートマッピング内のホストポートとコンテナポートが一致していないといけません。同じ数字にしても良いですが、Fargateではポートマッピングが動的に行われるため、コンテナポートのみを指定すれば良いです。`HostPort`を記載しない方が一般的かと思います。

```yaml
# NG例
PortMappings:
  - 
    ContainerPort: 80
    HostPort: 0
    Protocol: "tcp"
```

```yaml
# OK例
PortMappings:
  - 
    ContainerPort: 80
    Protocol: "tcp"
```

異なるポート番号を指定した場合、エラーメッセージは以下になります。

> Invalid request provided: Create TaskDefinition: When networkMode=awsvpc, the host ports and container ports in port mappings must match

## 注意点3：特定のCPUとメモリの組み合わせにする

`FARGATE`を使用している場合、特定のCPUとメモリの組み合わせを指定しない場合にエラーが発生します。例えば、CPUが`256(.25 vCPU)`の場合は、メモリは`0.5GB`から`2GB`の範囲である必要があります。

公式ドキュメントにも以下のように記載されています。

> requiresCompatibilities パラメータに FARGATE を指定しているタスク定義については (EC2 も指定されている場合も)、次の表のいずれかの値を使用する必要があります。これらの値によって、CPU とメモリのパラメータでサポートされる値の範囲が決まります。
> 引用元：https://docs.aws.amazon.com/ja_jp/AmazonECS/latest/developerguide/task-cpu-memory-error.html

上記の表に該当しない組み合わせを入れるとエラーになります。
エラーメッセージは以下。

> Resource handler returned message: "Invalid request provided: Create TaskDefinition: No Fargate configuration exists for given values: 900 CPU, 3400 memory. See the Amazon ECS documentation for the valid values.

## 注意点4:ターゲットタイプは`ip`
ECSタスクが`awsvpc`ネットワークモードで実行される場合、ELBのターゲットグループのターゲットタイプは`ip`である必要があります。先述の通り、`awsvpc`ネットワークモードでは、各タスクにENI(Elastic Network Interface)が割り当てられ、タスクはそのENIのIPアドレスを使用して通信します。固有のIPアドレスを持っているため、このタイプではないといけないんですね。

そのため、ターゲットグループはタスクのIPアドレスをターゲットとして使用するように設定する必要があるのです。ターゲットグループの定義で`TargetType`プロパティがあるので、その値を`ip`に設定する必要があります。具体的には以下の通り。

```yaml
TargetGroup:
    Type: "AWS::ElasticLoadBalancingV2::TargetGroup"
    Properties:
      HealthCheckIntervalSeconds: 5
      HealthCheckPath: "/"
      HealthCheckPort: "traffic-port"
      HealthCheckProtocol: "HTTP"
      HealthCheckTimeoutSeconds: 2
      HealthyThresholdCount: 2
      UnhealthyThresholdCount: 2
      Matcher:
        HttpCode: "200"
      Name: !Sub ${SysTag}-xxx
      Port: 80
      Protocol: "HTTP"
      TargetType: "ip" ## これを追加
      VpcId: !Ref VpcId
      TargetGroupAttributes:
        -
          Key: deregistration_delay.timeout_seconds
          Value: 0
```

`ip`を指定しない場合（ターゲットタイプがインスタンスになってしまっている場合）、以下のエラーメッセージが表示されます。

> Resource handler returned message: "Invalid request provided: CreateService error: The provided target group arn:aws:elasticloadbalancing:ap-northeast-1:1234567890123:targetgroup/xxxxx-xxxx/xxxx has target type instance, which is incompatible with the awsvpc network mode specified in the task definition.
WSLのバージョン確認とWSL自体のアップデート

WSL 2の話です

バージョン確認は`wsl -v`で、アップデートは`wsl --update`でできる

```
PS C:\> wsl -v
WSL バージョン: 2.0.14.0
カーネル バージョン: 5.15.133.1-1
WSLg バージョン: 1.0.59
MSRDC バージョン: 1.2.4677
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.25131.1002-220531-1700.rs-onecore-base2-hyp
Windows バージョン: 10.0.22631.3880

PS C:\> wsl --update
更新プログラムを確認しています。
Linux 用 Windows サブシステムをバージョンに更新しています: 2.2.4。
要求された操作には管理者特権が必要です。
更新プログラムを確認しています。
Linux 用 Windows サブシステムをバージョンに更新しています: 2.2.4。

PS C:\> wsl -v
WSL バージョン: 2.2.4.0
カーネル バージョン: 5.15.153.1-2
WSLg バージョン: 1.0.61
MSRDC バージョン: 1.2.5326
Direct3D バージョン: 1.611.1-81528511
DXCore バージョン: 10.0.26091.1-240325-1447.ge-release
Windows バージョン: 10.0.22631.3880

```
情報系大学生がサークルのホームページ作成してみた～github pagesで無料公開まで

# きっかけ

私は、情報系の3年生で、pythonを中心にプログラムは勉強してきましたが、webサイトなどは作ったことがなく、勉強も込めてwebサイト作ってみたいと思ったのきっかけです。どうせ勉強して何か作るなら、意味のあるものをつくってみたいと思ったので、自分が2年生の頃からの代表としていたサークル（ボランティア団体）のホームページ作ってみたいなと思い作成することにしました。

## ホームページ作成ツールは使わなかった理由

 webサイトがHTMLという言語で書かれていることは、知っていましたがホームページ作成などしたことがなかったため、まずどのようにしたら作れるのか調べることから始めました。どうやら、ホームページ作成ツール(WordPressなど）というものを使うと簡単にコード書かずに作れるとわかりましたが、自分は勉強のために、自分でコーディングして作ってみようと思いました。

 ## はじめにしたこと

 プログラミングはしたことがありましたが、HTMLとCSSとJavaScriptの知識は全くなかったので、とりあえず色んな記事をみたり,YouTubeなどの解説をみて、どのようにして、コードを書いていけばいいのかを勉強していきました。そしてとりあえず、転がっているサンプルのコードを参考に、ローカルでHTMLとCSSとJavaScriptでつくったりのを変更したりして、どのように動いているかなどを大まかに理解していきました。

## いざ作成

とりあえずは、webに転がっているテンプレートのコードを変えていきながら、色んなwebサイトを開発者ツールでどんなコードになっているのかを見ながら作っていきました。困ったときには、ChatGPTにも聞きながら、修正のつどどのような仕上がりに、なっているかを確認しながら作っていきました。

そのままHTMLファイルブラウザで開くとjQueryを使っていくうちに上手く開かくなったので、自分が作成しているフォルダで以下のようにコマンドを実行してpythonで検証用のwebサーバを起動していました。

```bash
 python -m http.server 8000
```

起動できたら
http://localhost:8000
から開いて確認。


 ## 作成をする上で工夫を行った点、苦労した点

 - **メニューボタンや、スライドショーの追加（jQueryを使用）**

メニューボタンを作ったり、スライドショーを追加して、それをcssできれいに整えるのに苦労しました。
 
 - **CSSでデザインとレイアウトを設定し、レスポンシブ対応**

スマホでも、パソコンでもレイアウト崩れないように、したかったので、レスポンシブ対応にするためのCSSを書いたりするのに苦労しました。

- **ブラウザのキャッシュ機能に苦労** 

少し修正しては、ブラウザでみていたので、ブラウザのキャッシュでうまく反映されないときもあり苦労しました。　そのときは、もう一度webサーバを起動しなおして対応しました。

- **更新が簡単にできるようにした**

一度、公開したら、新たな活動報告などの更新を手間なしでできるような形（型）をつくりました。


## Github Page でデプロイ

無料で広告も入らず、デプロイも簡単だということで、Github Pageでデプロイすることにしまいた。
以下の記事を参考にすぐにできました。

https://qiita.com/tsmog52/items/fc9e4be56a86d0f52f68

一度デプロイすれば、リポジトリの中の内容を変更するだけなので、変更は簡単です。

## GoogleAnalyticsを追加

どれくらいの方から見られるかも気になったので、以下の記事を参考にGoogleAnalyticsで分析できるようにしまいた。

https://qiita.com/chikurin66/items/b776c9a2e5a8ebf0dd68


個人的に数値分析などが好きなので、定期的にチェックしたいなと思っています。

 ## 感想

最初はかなり苦戦しましたが、開発者ツールで色々なサイトをみてみたり、自分で１から作ったのですごく勉強にもなりました。ウェブの基本的な知識も着いたので、やって良かったなと思っています。
また何より、自分で、意味のあるホームページを作れて、楽しかったです。

ちなみに私が作成したホームページは以下になります。

https://lalala-takahira.github.io/homepage/
[IT勉強会レポート]おもにクラウドの話してます - 広島 #2

こんにちは。Kaneyasuです。
本記事はIT勉強会の開催レポートです。

2024/06/28におもにクラウドの話してます - 広島というオフラインイベントの2回目を開催しました。

https://omoni-cloud.connpass.com/event/320415/

こちらの勉強会はクラウド全般の勉強会となっております。
3大クラウドだけでなく、SaaS、データレイク、クラウドに対する疑問もOKとしています。

# 当日の様子

Togetterでまとめております。
こちらで雰囲気をご覧ください！

https://togetter.com/li/2392650

発表者の皆様、参加者の皆様、ありがとうございました！
会場を貸してくださったサイボウズ広島オフィス様、ありがとうございました！

https://page.cybozu.co.jp/-/cybozu-hiroshima/

# 当日の発表

6人も発表してくださいました。（最後のは私です。）
ありがとうございます！

## 事業会社で基幹業務システムを10年ほどAWSで運用してみた　ドキュメント編

https://x.com/mu2in/status/1806637521272811773

k2worksさんの発表です。
長期間業務システムと向き合っているk2worksさんならではの発表でした。
全体的に技術に対してとても感度が高いことがわかります。
2013年にすでに設計書をマークダウンで書かれてたということでしたが、これは相当早いです。
当時私は普通のSIerだったので、へーそんな世界もあるんだなーぐらいだったので驚きました。
ご本人は1人情シスだからと仰っていましたが、キャッチアップの速さと挑戦する姿勢に尊敬の念を抱きました。

## release-please で実現する、手軽で不変な Docker イメージタグ付け方法

https://speakerdeck.com/chanyou0311/release-please-teshi-xian-surushou-qing-tebu-bian-na-docker-imesitakufu-kefang-fa

chanyouさんの発表です。

発表内で新しいキーワードをいくつも聞いたので、ポインタをまとめておきます。

https://cloud.google.com/architecture/best-practices-for-building-containers?hl=ja#properly_tag_your_images

https://www.conventionalcommits.org/ja/v1.0.0/

https://semver.org/lang/ja/

https://github.com/googleapis/release-please

コンテナを使ったシステムにおいて、Immutableを実現することが重要。
それを実現するためのタグを自動生成する仕組みとして、Convention Commitsとrelease-pleaseを使うとのことでした。
私、今までConvention Commitsの利点をあまり感じていなかったのですが、こんな使い方もあるんですね。

そして、実際に目の前でデプロイしている様子を見せていただきました。
すげぇ。

https://blog.chanyou.app/posts/omokura-2/

## スタートアップの開発とクラウドサービス

https://speakerdeck.com/tsankyo/sutatoatupunokai-fa-tokuraudosabisu

3to_dayさんによる発表です。

私も昔プロダクトの初期に関わっていました。
ゼロから1の話を聞いて、ウッってなりました。
初期の立ち上げは本当に大変ですね。

GitHub Actionsの話を聞いて、AWS CodePipelineだけでなくGitHub Actionsも覚えないとダメだなと勝手に危機感を覚えていました。
「AppSheetとMetabaseの話のポイントは、課題解決を最優先として作りやすいツールを使っていることと、それを分析にまで繋げていることですね。
目的を優先とした選定をされてることを感じました。

https://github.co.jp/features/actions

https://cloud.google.com/appsheet?hl=ja

https://www.metabase.com/

## 【LT】ポチっとな！でクラウド簡単呼び出し

LTのお一人目はOzakiさん

https://speakerdeck.com/ozk009/potitutona-dekuraudojian-dan-hu-bichu-si

SORACOM > Lambda > Slack という構成で、IoTのボタンを押すとSlackに通知が行くという構成。
応用した会議脱出ボタンはいいアイデアですね。
私もその昔深夜残業に抜け出すために家族からそれっぽい電話をかけてもらったことがあります。
許してください・・・。

https://soracom.jp/

## 【LT】バックアップしていますか？

tsuda_ahrさんのLTです。

https://speakerdeck.com/tsudaahr/batukuatupusiteimasuka

最近はシステム絡みで穏やかでないニュースが多いので、考えさせられるテーマですね。
クラウドエンジニアとして補足すると、クラウドベンダーも最後は人なので、念のためリージョン間コピーまで考えることはあります。

## 【LT】Conoha VPSでlaCはできる！

yuxkiさんのLTです。

https://www.conoha.jp/

レンタルサーバーのConohaを使い倒してみたお話でした。
ものすごい低コストでさまざまなことをしていて、すごくいいLTでした。
限られたリソースでどこまでできるか考えるのは楽しいですよね。
Conohaの人、それは想定外かも？といところまで行っていて素晴らしかったです。

## AWS CodeGuruでPythonのコードを自動レビューしてもらおう

最後は、私です。

https://speakerdeck.com/satoshi256kbyte/aws-codegurudepythonnokodowozi-dong-rebiyusitemoraou

人力によるコードレビューが大変なので自動レビューを試してみました。
言語はPythonです。
感触としてはレビュー内容はFlake8の120％くらいの内容でしたね。
この時はAWS CodeCommitで試しましたが、今後GitHubでの検証をやろうと思います。

# 最後に

今回も自分は知ってるけど他の人は知らないかも・・・というのが集っている感じがして、とても嬉しかったです。

日々の業務が忙しいと、業務と直接関係ないことにそんなに時間は使えません。
この勉強会は良くも悪くもクラウドを中心としたごった煮の勉強会なので、来ていただければ何かしら新しい情報を得られると思います。
これからもそんな勉強会を続けていきたいと思います。
ChatGPTに手が追い付かない！

# ChatGPT依存
現在、私は毎日、何度もChatGPTを起動して、仕事やプライベートに活用しています。その用途は非常に幅広く、多岐にわたっている。

## 活用事例
- 顧客への提案資料の大枠作成:
  - 顧客の要望を踏まえた提案資料の骨組みをChatGPTに作成してもらい、その上に詳細を加えていく
- アイディアだし時の壁打ち:
  - 新しいアイディアやプロジェクトの初期段階で、ChatGPTを相手にブレインストーミングを行い、アイディアの整理や発展を図る
- プライベートでのコーディング、DB設計、テストコード作成:
  - 自宅での個人プロジェクトや学習の際にも、ChatGPTを活用して効率的にコーディングや設計、テストコードの作成を行う

# 生成AIを最大限活用できるのか
既にプロンプトによって生成AIに複数の役割を与え、議論させることも可能になっている。その先に待っているのはどんな世界だろうか。

## 複数の生成AIの同時利用
複数の生成AIを同時に活用することにも期待される。例えば、異なる専門分野のAIを連携させることで、より多角的な視点からのアドバイスや情報提供が可能になります。これにより、より包括的で質の高い成果物を作成できるようになると考えています。

## 生成AIに生成AIを操作させる
さらに、生成AIに他の生成AIを操作させることも視野に入れています。例えば、ある生成AIが別の生成AIに特定のタスクを依頼し、その結果を統合することで、より高度なアウトプットを実現することができます。このような多層的なAI活用により、効率と成果のさらなる向上が期待されます。
Chart.js の基礎

Chart.js は、ウェブページに様々な種類のグラフを簡単に実装できる、人気のある JavaScript ライブラリです。シンプルで使いやすく、豊富なカスタマイズオプションを備えているため、データ可視化の幅広いニーズに対応できます。この記事では、Chart.js の基本的な使い方を解説します。

### 1. Chart.js のインストール

まずは、Chart.js をプロジェクトにインストールします。npm や yarn を使用できます。

```bash
npm install chart.js
```

### 2. キャンバスの準備

Chart.js は、HTML の `<canvas>` 要素にグラフを描画します。`<canvas>` 要素を HTML に追加します。

```html
<canvas id="myChart"></canvas>
```

### 3. チャートの作成

JavaScript で Chart.js を使用して、チャートを作成します。

```javascript
// Chart.js をインポート
import Chart from 'chart.js';

// キャンバスを取得
const canvas = document.getElementById('myChart');

// チャートのコンテキストを取得
const ctx = canvas.getContext('2d');

// チャートのデータ
const data = {
  labels: ['月', '火', '水', '木', '金'],
  datasets: [{
    label: '売上',
    data: [10, 20, 30, 40, 50],
    backgroundColor: 'rgba(54, 162, 235, 0.2)',
    borderColor: 'rgba(54, 162, 235, 1)',
    borderWidth: 1
  }]
};

// チャートのオプション
const options = {
  responsive: true,
  scales: {
    y: {
      beginAtZero: true
    }
  }
};

// 折れ線グラフを作成
const myChart = new Chart(ctx, {
  type: 'line',
  data: data,
  options: options
});
```

このコードでは、`labels` にグラフの軸ラベル、`datasets` にデータセットを定義しています。`datasets` 内の `data` には、それぞれのラベルに対応する値を配列で指定します。

`type` には、グラフの種類を指定します。Chart.js は、折れ線グラフ (`line`)、棒グラフ (`bar`)、円グラフ (`pie`)、ドーナツグラフ (`doughnut`) など、様々な種類のグラフに対応しています。

### 4. オプションの設定

`options` オブジェクトを使って、グラフの外観や挙動をカスタマイズできます。

* **`responsive`:** 画面サイズに合わせて自動調整するか設定します
* **`scales`:** 軸の範囲やラベルなどを設定します
* **`legend`:** 凡例の設定を行います
* **`title`:** グラフのタイトルを設定します

### 5. データの更新

`update()` メソッドを使って、チャートのデータを更新できます。

```javascript
// データを更新
myChart.data.datasets[0].data = [60, 70, 80, 90, 100];

// チャートを更新
myChart.update();
```

### まとめ
プロジェクトで使用する機会がありましたので使い方をまとめてみました。
これ一つで色々なグラフの生成ができるので便利ですね。
実際に色々と作成してみたいと思います。
package.jsonの基礎

package.jsonは、プロジェクトのレシピのようなものです。
プロジェクトの構成や必要な材料（依存関係）を詳細に記述することで、プロジェクトの構築と管理をスムーズに行うことができるのですが中身を理解していない部分もありましたので確認していきたいと思います。

**1. プロジェクトの基礎情報**

* **name**: プロジェクトの名前です。パッケージを公開する際に使われます
* **version**: プロジェクトのバージョン番号です。semver（Semantic Versioning）と呼ばれるルールに従って、バージョン管理を行います
* **description**: プロジェクトの説明文です。プロジェクトの内容を簡潔に説明します

**2. コマンドライン: scripts**

* **scripts**: プロジェクトの様々な操作をコマンドラインで実行するための定義です
    * **serve**: 開発サーバーを起動して、プロジェクトをローカルで確認するためのコマンドです。`npm run serve`で実行します
    * **build**: プロジェクトをビルドして、本番環境用のコードを生成するためのコマンドです。`npm run build`で実行します
    * **lint**: コードのスタイルや構文をチェックするコマンドです。`npm run lint`で実行します
    * さらに、独自のスクリプトを追加することも可能です

**3. プロジェクトに必要な材料: dependencies**

* **dependencies**: プロジェクトの実行に必要なパッケージ（ライブラリ）のリストです
    * **vue**: Vue.jsの本体ライブラリ。Vue.jsの機能をすべて提供します
    * **vue-router**: Vue Routerのライブラリ。Vue.jsアプリケーションのルーティング機能を提供します
    * 他の必要なライブラリもここに記述します

**4. 開発に必要な材料: devDependencies**

* **devDependencies**: プロジェクトの開発時に必要なパッケージのリストです
    * **@vue/cli-service**: Vue CLIのコアとなる部分を提供します
    * **@vue/cli-plugin-babel**: Babelのプラグイン。JavaScriptのコードを様々なブラウザで動作するように変換する機能を提供します
    * **@vue/cli-plugin-eslint**: ESLintのプラグイン。コードのスタイルや構文をチェックして、より良いコードを作成するための機能を提供します
    * **eslint**: JavaScriptのコードリンティングツール。コードのエラーや潜在的な問題点を検出します
    * **eslint-plugin-vue**: Vue.js用のESLintプラグイン。Vue.jsのコードのリンティングを行います
    * **vue-template-compiler**: Vue.jsのテンプレートをJavaScriptのコードに変換するコンパイラ

**5. プロジェクトの情報: authorとlicense**

* **author**: プロジェクトの作者の名前です
* **license**: プロジェクトのライセンスです。著作権や利用規約を定めます

**package.jsonの使い方**

* **インストール:** `npm install`コマンドで`dependencies`と`devDependencies`に記載されたパッケージをインストールします
* **実行:** `npm run serve`や`npm run build`などのコマンドで、`scripts`に定義されたスクリプトを実行します
* **バージョン管理:** プロジェクトのバージョンアップに合わせて、`version`フィールドを更新しま

**まとめ**

package.jsonは、プロジェクトを作成する際に自動的に作成されるため中身の理解ができていませんでした。
今回まとめたことにより理解を深めることができました。
プロジェクトの依存関係やスクリプトを正しく定義することで、開発をよりスムーズに行うことができるためしっかりと理解した上で使っていきたいです。
axiosで2つのjsonファイルを読み込む時に気を付けるべき事

axiosで2つのjsonファイルを読みこもうとVueでこういうコードを書いてました
``` 
onMounted(() => {
    axios
        .get('http://hogehoge')
        .then((res1) => (tar1.value = res1),
    axios
        .get('http://fugafugra')
        .then((res2) => (tar2.value = res2)
})
```
こう書いた時、どうやら非同期処理のせいで
1個目のaxiosが発火したのと同時に2個目のaxiosが発火しres1にhogehogeから得られるjsonファイルが消えてしまい、res1.valueは宣言した時の値になりました。
それの対策として
```
onMounted(async () => {
    await axios
        .get('http://hogehoge')
        .then((res1) => (tar1.value = res1),
    axios
        .get('http://fugafugra')
        .then((res2) => (tar2.value = res2)
})
```
この様にasyncとawaitを用いて同期処理を行う事で解決できました。

### これからの課題
* 非同期処理とはあるが、どのタイミングで2つ目のaxios処理が走ったか調べる方法を見つける。
未来を創るブロックチェーンの世界

# はじめに
こんにちは、web3に興味があるエンジニアです！
近年、ブロックチェーン技術は何度も注目を集めており、今も進化を続けています。その魅力と可能性を一緒に探っていきましょう。

# 対象読者
- ブロックチェーンに興味のある方
- 技術トレンドを追いかけるのが好きな方
- ブロックチェーンを使ってみたいと思っているエンジニアの方

# 目次
1. ブロックチェーンとは？
2. ブロックチェーンの基礎技術
    * ハッシュ関数
    * 非対称暗号
    * コンセンサスアルゴリズム
3. ブロックチェーンの実際の利用例
4. ブロックチェーンの最新トレンド
    * DeFi（分散型金融）
    * NFT（非代替性トークン）
    * Web3
5. ブロックチェーン導入のベストプラクティスと注意点
6. まとめ

# 1. ブロックチェーンとは？
ブロックチェーンと聞いて、あなたは何を思い浮かべますか？ビットコインや仮想通貨でしょうか？
実際、それも間違っていませんが、ブロックチェーンの魅力はそれだけではありません。ブロックチェーンは分散型のデジタル台帳であり、データを安全かつ信頼性高く管理するための技術です。ここでは、その基本をわかりやすく説明していきます。

## ブロックチェーンの基本
ブロックチェーンとは、連続して結ばれたデータのブロックのこと。各ブロックには、タイムスタンプと前のブロックへのリンクが含まれています。これにより、改ざんが非常に困難な構造が作り上げられます。

# 2. ブロックチェーンの基礎技術
ブロックチェーンの魅力は、その技術的な基盤にもあります。以下はその中核を担う技術です。

## ハッシュ関数
ハッシュ関数は、入力データを固定長の値に変換する関数です。これにより、入力データが僅かに変わるだけで、異なる出力が生成されるため、ブロックチェーン上のデータの改ざんを防ぐ役割を果たします。

## 非対称暗号
非対称暗号は、公開鍵と秘密鍵という2つの異なる鍵を使用してデータの暗号化と復号化を行います。これは、データの真正性と整合性を保証するために重要です。

## コンセンサスアルゴリズム
ブロックチェーンの非中央集権性を支えるために、ノード間で合意を形成するアルゴリズムが使われます。例えば、ビットコインではProof of Work（PoW）が使用されています。

# 3. ブロックチェーンの実際の利用例
ここからは、ブロックチェーン技術が実際にどのように使われているのか、具体例を見ていきましょう！

## 仮想通貨
まずはやはり、ビットコインやイーサリアムなどの仮想通貨です。これらはブロックチェーン技術の最も有名な応用例ですね。

## スマートコントラクト
スマートコントラクトは、契約内容をプログラム化し、自動的に実行する技術です。これにより、仲介者を必要とせずに、公平かつ信頼性の高い取引が可能になります。

## サプライチェーン管理
サプライチェーン管理において、ブロックチェーン技術は商品の追跡と透明性を向上させるために活用されています。💡

# 4. ブロックチェーンの最新トレンド
ブロックチェーンは常に進化しています。最近のホットな話題もしっかり押さえておきましょう。

## DeFi（分散型金融）
DeFiは中央集権的な金融機関を介さずに、金融サービスを提供する新しい形の金融システムです。イーサリアムを基盤としたプロジェクトが多く、貸し付けや取引、投資まで幅広いサービスが提供されています。

## NFT（非代替性トークン）
NFTは、ユニークなデジタル資産の所有権を証明するトークンです。アートやゲームアイテムなど、デジタルコンテンツの所有権をブロックチェーン上で管理します。

## Web3
Web3は次世代のインターネットとされています。ブロックチェーンを基盤とし、ユーザーが自身のデータをコントロールできる非中央集権的なウェブを目指します。🚀

# 5. ブロックチェーン導入のポイント
最後に、ブロックチェーンを実際に導入する際のポイントと注意点に触れましょう。

## 導入のポイント
- **目的を明確にする**: ブロックチェーンが本当に必要かを判断することが重要です。
- **適切なコンセンサスアルゴリズムを選ぶ**: システムの要件に合ったアルゴリズムを選択しましょう。
- **セキュリティ強化**: ハッシュ関数や非対称暗号の運用を徹底しましょう。

## 注意点
- **規制と法律**: ブロックチェーンに関連する法律や規制を十分に理解し、遵守することが重要です。
- **スケーラビリティ問題**: 特にパブリックブロックチェーンは、トランザクション処理速度等のスケーラビリティの問題を持つことが多いです。

# まとめ
ブロックチェーンの魅力とその技術、実際の利用例、そして最新トレンドについて、分かりやすく解説しました。ブロックチェーンの可能性はまだまだ広がっており、今後の技術革新からも目が離せません。ブログを読んで「なるほど！」と思ってもらえたなら、とても嬉しいです！
npm、yarn、npx：Node.jsパッケージ管理

Node.jsのパッケージ管理は、開発の効率化に欠かせない要素です。しかし、npm、yarn、npxといったツールが登場し、それぞれに特徴があるため、どれを使えばいいのか迷ってしまう人も多いでしょう。私も普段何気なく使っているためなんでそれを使用した方がいいのかあまり詳しくわからなかったためまとめてみました。

**1. npm (Node Package Manager)**

npmはNode.jsのパッケージマネージャーとして、最も広く利用されています。Node.jsと一緒にインストールされ、初期から存在するツールです。

**メリット:**

* **シンプル:**  基本的なパッケージのインストール、更新、アンインストールなどの操作は簡単に行える
* **豊富なパッケージ:** npmレジストリには膨大な数の公開パッケージが存在し、ほとんどのニーズを満たせる
* **コミュニティ:**  npmは最も人気のあるパッケージマネージャーであるため、多くのコミュニティサポートとドキュメントがある

**デメリット:**

* **速度:** パッケージのインストールや更新に時間がかかる場合があり、大規模なプロジェクトでは特に顕著です
* **セキュリティ:**  パッケージの依存関係が複雑になると、セキュリティ上の問題が発生する可能性がある
* **柔軟性の欠如:**  npmは比較的柔軟性に欠け、複雑なワークフローに対応するのが難しい場合がある

**2. yarn (Yet Another Resource Negotiator)**

yarnはnpmの代替として登場したツールで、npmの欠点を克服するために開発されました。

**メリット:**

* **高速:**  パッケージのインストールや更新が高速で、npmよりも大幅なパフォーマンス向上を実現している
* **オフラインモード:**  一度パッケージをインストールすると、オフライン環境でも使用できる
* **セキュリティ:**  依存関係をロックすることで、セキュリティリスクを軽減することができる
* **柔軟性:**  ワークスペースやプラグインなどの機能により、複雑なプロジェクトにも対応できる

**デメリット:**

* **学習コスト:**  npmに比べて、新しいコマンドや設定を覚える必要がある
* **コミュニティ:** npmほど広範なコミュニティサポートがない

**3. npx (npm Package Executor)**

npxはnpm 5.2以降に導入されたツールで、パッケージを実行するためのコマンドです。

**メリット:**

* **パッケージの実行:**  ローカルまたはグローバルにインストールされたパッケージを簡単に実行できる
* **バージョン管理:**  パッケージの特定のバージョンを実行できる
* **依存関係の解決:**  必要な依存関係を自動的にインストールする

**デメリット:**

* **npmの依存:**  npxはnpmに依存するため、npmがインストールされていないと使用できない

**まとめ: どのツールを選ぶべきか？**

* **初心者:** npmはシンプルで使いやすく、基本的なパッケージ管理に最適です
* **速度とセキュリティを重視:**  yarnは高速でセキュリティ対策も強化されており、大規模なプロジェクトに適しています
* **パッケージの実行:**  npxはパッケージの実行に最適です

開発プロジェクトの規模や要件に応じて、最適なツールを選択してください。最新のトレンドでは、yarnがより人気を集めている一方で、npmは依然として広く使われています。npxは、npmやyarnの機能を拡張する便利なツールです。

**最後に:**

npm、yarn、npxはそれぞれ長所と短所があることがわかりました。これを使用するというよりかはプロジェクトによって使い分けていく方がいいと感じました！
FastAPIでWebSocketの超入門


FastAPIを使って簡単にWebSocketで送受信する

## websocketsをインストール

FastAPIでWebSocketを実装するために、`websockets`をインストールする。

```python
pip install websockets
```

##  やってみる

`accept`で受信待ちして、クライアントと接続したら、`receive_text`と`send_text`で送受信する。

```python
await websocket.accept()
while True:
    data = await websocket.receive_text()
    await websocket.send_text(f"Message text was: {data}")
```

## コネクションが切断した場合は例外が発生する

コネクションが切断されると、`receive_text`メソッドで`WebSocketDisconnect`の例外が発生する。
相手がすでにコネクションを切断していると`send_text`でも同様に例外が発生する。


```python
try:
    while True:
        response = await websocket.receive_text()
        logger.info(f"receive {response}")
        await asyncio.sleep(10)
        await websocket.send_text(f"Message text was {response}")
        logger.info("send message")
except WebSocketDisconnect:
    logger.error(traceback.format_exc())
```

## パスやクエリー情報も取得可能

PathやQueryの情報も取得できる。

```python
async def get_cookie_or_token(
    websocket: WebSocket,
    session: Union[str, None] = Cookie(default=None),
    token: Union[str, None] = Query(default=None),
):
    if session is None and token is None:
        raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
    return session or token


@app.websocket("/items/{item_id}/ws")
async def websocket_endpoint(
    websocket: WebSocket,
    item_id: str,
    q: Union[int, None] = None,
    cookie_or_token: str = Depends(get_cookie_or_token),
):
```


## 最後に

FastAPIを使って簡単にサーバ側がWebSocketの実装ができることがわかった。FastAPIのページにセッションの管理の
サンプルも載っているので参考にしたらいいかと思う。

## 参考

https://fastapi.tiangolo.com/ja/advanced/websockets/