OmniAICreator/Qiita-1.07M huggingface dataset:
Tokenizerが出したトークンをいじってみると...

LLMでは，文字列は全て「トークン: Token」で扱われています．Tokenizerが扱うことのできるトークンの集合のことをボキャブラリといいます．ボキャブラリの中には，文字列として見ると同じなのに，違うトークン番号として登録されているトークンがあります．

この記事では，文字列としては同じだが，Tokenizerが出力したものとは違うトークン番号をモデルに与えた時に何が出力されるのかを見てみます．

## 使用したモデル
https://huggingface.co/vicgalle/gpt2-open-instruct-v1

## 普通に文字列生成を行う
まずは普通にプロンプトをTokenizerに通し，その出力をそのままモデルへ流します．プロンプトは"In 2020,"とします．
```python
inputs = tokenizer('In 2020,', return_tensors="pt")
input_ids = inputs.input_ids
attention_mask = inputs.attention_mask
outputs = model.generate(input_ids=input_ids, attention_mask=attention_mask)
tokenizer.batch_decode(outputs)[0]
```
```text
In 2020, the United States had a population of approximately 1.3 billion people.\n\nThe
```

さて，この時，入力としてモデルに受け渡されたトークンを見ると・・・
```python
>>> input_ids
tensor([[  818, 12131,    11]])
```
3つのトークンしか使われていません．実は，" 2020"という文字列が1つのトークン（トークン番号12131）として認識されています．
```python
vocab = tokenizer.get_vocab()
ivocab = {tid:ttx for ttx,tid in vocab.items()}
for tid in input_ids[0].numpy():
    print(tid, ivocab[tid])
```
```text
818 In
12131 Ġ2020
11 ,
```
"Ġ"というのは空白を意味していると思われます．

## トークンをあえて細分化してみる
先ほどは，" 2020"という文字列は1つのトークンとして処理されていましたが，これを" 2","0","2","0"の4つのトークンに細分化してからモデルに渡すとどうなるのでしょうか？

まずはそれぞれのトークン番号を探します．
```python
for text in [" 2","0","2","0"]:
    print(text, tokenizer(text).input_ids[0])
```
```text
 2 362
0 15
2 17
0 15
```
このトークン番号で`input_ids`を置き換えます．
```python
input_ids = tensor([[818, 362, 15, 17, 15, 11]])
attention_mask = ones_like(input_ids)
tokenizer.batch_decode(input_ids)
```
```text
['In 2020,']
```
トークン番号は変わりましたが，文字列にしてしまえば違いが見当たりません．これをモデルに入れるとどうなるでしょう．
```python
outputs = model.generate(input_ids=input_ids, attention_mask=attention_mask)
outputs
tokenizer.batch_decode(outputs)[0]
```
```text
In 2020, 2160, 2160, 2160, 2160, 2160
```

## 比較する
| |Tokenizerが出力したオリジナル|細分化したもの|
|---|---|---|
|トークン|`818,12131,11`|`818, 362, 15, 17, 15, 11`
|出力文字列|In 2020, the United States had a population of approximately 1.3 billion people.\n\nThe|In 2020, 2160, 2160, 2160, 2160, 2160

トークンの文字列表現はどちらも"In 2020,"ですが，細分化したものの方では，出力文字列の文脈が破綻しています．
文字列としては同じように見えても，トークン番号としては異なる意味を持っているみたいです．
【React】Create React AppへのTailwind CSS導入手順

## はじめに

Create React AppでTailwind CSSを導入する手順について記載します。

基本的にTailwindの公式サイトでの紹介通り進めていき、適宜補足します。

https://tailwindcss.com/docs/guides/create-react-app

:::note warn
Create React Appの使用はもはや推奨されていないようです（詳細は参考サイトをご確認ください）
使用される場合はご自身の判断でお願いします。
:::

## 環境

- 作業日: 2023/12/23
- OS： M1 mac/Sonoma version14.2.1
- React: 18.2.0
- Node.js: v20.9.0
- Tailwind: v3.4.0

## 手順

### 1. Reactアプリのプロジェクトの作成

すでに作成済みの場合は飛ばして2.へどうぞ。
my-projectの部分は好きなプロジェクト名を入れてください。

```bash
npx create-react-app my-project
```

### 2. 作成されたディレクトリへの移動

```bash
cd my-project
```

### 3. Tailwind CSSのインストール

```bash
npm install -D tailwindcss
```

### 4. 設定ファイルの追加

```bash
npx tailwindcss init
```

実行するとsrc/以下にtailwindの設定ファイル `tailwind.config.js` が作成されます。

```javascript:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
  theme: {
    extend: {},
  },
  plugins: [],
}
```

### 5. 設定ファイルへのパスの記載

4.で作成された `tailwind.config.js` にこれから作っていくReactのコンポーネントのパスを追加します。

```diff_javascript:tailwind.config.js
/** @type {import('tailwindcss').Config} */
module.exports = {
+  content: [
+    "./src/**/*.{js,jsx,ts,tsx}",
+  ],
  theme: {
    extend: {},
  },
  plugins: [],
}
```

### 6. index.cssへの設定追加

Tailwindを使用できるよう、`./src/index.css`に以下を追加します。

```css
@tailwind base;
@tailwind components;
@tailwind utilities;
```

### 7. Reactアプリの起動

`my-project/`以下でコマンドを実行し、Reactアプリを起動します[^1]。

```bash
npm run start
```

ブラウザが立ち上がり、`http://localhost:3000/`へ接続されます。

### 8. Tailwindを使用してみる

早速Tailwindを試してみます。
App.jsに適当なHTMLを書き、className属性にTailwindのクラス名を指定します。すると、Tailwindで用意されているスタイルを適用できます。

:::note warn
`./index.css` のimportをお忘れなく！
:::

#### 例1

```react:./src/App.js
import './index.css';

export const App = () => {
  return (
    <>
      <h1 className="text-3xl font-bold underline">Hello world!</h1>
    </>
  );
};
```

![スクリーンショット 2023-12-23 14.52.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/c3af25e9-d371-dbe1-8f68-a663df06b537.png)

#### 例2

```react:./src/App.js
import './index.css';

export const App = () => {
  return (
    <>
     <div className="border border-gray-400 rounded-2xl p-2 m-2 flex justify-around items-center w-80">
        <p className="m-0 text-gray-400">Tailwind CSSを試してみた</p>
        <button className="bg-gray-300 border-0 p-2 rounded-md hover:bg-gray-400 hover:text-white">ボタン</button>
     </div>
    </>
  );
};
```

![スクリーンショット 2023-12-23 14.50.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/911578/2f6973f8-780a-b74b-56ca-66a023ec2b92.png)

## 終わりに

2021年9月に出版された『モダンJavaScriptの基本から始める　React実践の教科書』を使用して学習しており、紹介されたTailwindを試そうとしましたが、本で紹介されているやり方ではバージョンの違いでうまくいかなかったので、公式サイトを見て実施しました。

https://www.sbcr.jp/product/4815610722/

## 参考サイト

### Create React Appについて

https://create-react-app.dev/

https://zenn.dev/nekoya/articles/dd0f0e8a2fa35f

### npm start

https://stackoverflow.com/questions/51358235/is-there-a-difference-between-npm-start-and-npm-run-start

[^1]:`npm start` は `npm run start` のエイリアスなので、この2つの挙動は同じのようです。
Rails6.0系からRail7.0系へのアップデート準備

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー20日目です。

今開発しているアプリがRails6系なので、これを7系にアップデートするにあたり必要な情報を集めます。

# 前提
### テストコード必須
アプリケーションのコアとなるロジックを中心に、挙動がおかしくならないかを自動で確認するテストを書いておく。
テストがないと、アプリの挙動全てを手動で確認しなければならない。普段から行っていなければ漏れが出るし、アプリの機能の規模が大きくなれば全て手動でやるのはコストがかかる。

# 実施手順
### 公式のアップグレードガイドに目を通し、確認が必要そうなところに目星をつけておく
https://railsguides.jp/upgrading_ruby_on_rails.html#rails-6-1%E3%81%8B%E3%82%89rails-7-0%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89

### ブランチを作成する

Railsのバージョンアップの際は、以下のような命名規則にするとよさそう。

```shell:ブランチ
develop ━ feature/rails_update_6.x ┳ feature/rails_6-x_update_xxx
                                   ┣ feature/rails_6-x_update_rails
                                   ┗ feature/rails_6-x_fix_xxx
```

### Rails以外のGemのアップデート
影響の小さそうなものから順番に行っていく。
`bundle outdated`を使うと必要なGemを炙り出せる。最近は結構見やすい形で出してくれるらしい。

Rails以外を`bundle update --conservative <gem名>`でバージョンアップ`--conservative`オプションにより、指定したgemと指定したgemが直接依存しているgemのみバージョンアップするようになる。

deviseは影響が大きそうなので、CHANGE LOGを確認するなどして慎重に行うこと。

https://github.com/plataformatec/devise/blob/master/CHANGELOG.md

あとは、bundle updateでまとめてやる。もう一回bundle outdatedで確認.

### Railsのパッチバージョンを最新にする
いきなり6.xxから7に上げるのではなく、パッチバージョンを最新に上げる。テストを実行してきちんと動くことを確認。

### Railsのメジャーバージョンを上げる
GemfileのRailsのバージョンを指定し、`bundle update`を実行。

### rails app:updateを実行
バージョンアップにあたり、必要なファイル作成やファイル更新を対話的に行える。



# 検討事項
参考：
https://railsdiff.org/

### 先にRubyのバージョンをアップデートするか
今回はRubyはすでに3系を利用している。Rails7にすることができるバージョンなので、このタイミングでは必要ないかも。ただし、Railsのバージョンが上げ終わったらすぐにRubyのバージョンも上げておきたい。こまめにアップデートすることが無用なトラブル回避に繋がる。

### importmapsを使うか
結論、使わないでよさそう。その場合は一旦`bin/dev`の実行で凌ぐが、Procfile周りの取り扱いについて調べる必要がある。

### デプロイはどうなるか
現状、PaaSに直接プッシュしてデプロイしている状態。Rails7に上げることで、そのプロセスに何か変化があるか。

### 必要そうな対応

#### アップデート前

**オートローダー設定**
以下を参考にオートローダーを変更しておく
https://railsguides.jp/classic_to_zeitwerk_howto.html

#### アップデート後

**Sprokets**
Sproketsを使っているので、Gem`sprokets-rails`をGemffileに追記する必要がある。

**外部ページへのリダイレクトの挙動**

外部ページへのリダイレクトが最初から無効になっている。

[§3.10.16 `config.action_controller.raise_on_open_redirects` -- Configuring Rails Applications — Ruby on Rails Guides](https://edgeguides.rubyonrails.org/configuring.html#config-action-controller-raise-on-open-redirects)

以下のように書くことでリダイレクトを一時的に有効にできる。

```ruby
redirect_to authorize_uri, allow_other_host: true unless sign_in?
```

# 参考にする記事
https://railsguides.jp/upgrading_ruby_on_rails.html#rails-6-1%E3%81%8B%E3%82%89rails-7-0%E3%81%B8%E3%81%AE%E3%82%A2%E3%83%83%E3%83%97%E3%82%B0%E3%83%AC%E3%83%BC%E3%83%89

https://qiita.com/jnchito/items/0ee47108972a0e302caf

https://tech-book.precena.co.jp/software/backend/ruby-on-rails/upgrade-6-1-to-7-0

https://techracho.bpsinc.jp/konaga/2022_12_22/125929

https://railsdiff.org/

https://zenn.dev/redheadchloe/articles/946b478085f9c1
DockerfileのCMDとENTRYPOINTの違い

Dockerfile作成時に頻繁に使用する2つの命令、`CMD`と`ENTRYPOINT`について解説します。この2つの命令は、コンテナの実行時のコマンドや引数を指定するために使われますが、その使い方や役割には差異があります。

## CMDとENTRYPOINTの基本

- Dockerfileでは、`CMD`と`ENTRYPOINT`をそれぞれ何度でも記述することが可能です。しかし、各命令が複数回記述されている場合、その中の最後に記述されたものだけが最終的に使用されます。つまり、1つのDockerfileで有効な`CMD`と`ENTRYPOINT`はそれぞれ1つずつということです。
- `CMD`と`ENTRYPOINT`が指定するコマンドや引数は、`docker run`の実行時にコンテナ内で動作します。

### ENTRYPOINT

`ENTRYPOINT`命令は、コンテナを起動するときに必ず実行されるコマンドを指定します。このコマンドは`docker run`の際に`--entrypoint`オプションを使用して上書きすることができます。

### CMD

一方、`CMD`命令は`ENTRYPOINT`で指定されたコマンドの引数または`ENTRYPOINT`が指定されていない場合のデフォルトのコマンドを決める役割を果たします。`docker run`の実行時に簡単に上書きすることが可能です。また、引数が不要な場合は、`ENTRYPOINT`のみで十分です。

例えば以下のDockerfileでは、

```dockerfile
FROM ubuntu
ENTRYPOINT ["echo"]
CMD ["Hello, Docker!"]
```

ここでは、`ENTRYPOINT`で"echo"というコマンドを指定し、その引数として"Hello, Docker!"を`CMD`で定義しています。これにより`ENTRYPOINT`のコマンドが固定され、`CMD`で指定した引数は必要に応じて上書きすることができます。

例えば、次のように実行すると：

```bash
docker run <イメージ名> "Hello, World!"
```

出力は「Hello, World!」になり、`CMD`で指定したデフォルトの引数が上書きされた結果が結果として出力されます。

一方、引数が不要な場合、`ENTRYPOINT`のみでもコマンドの実行は可能です。その場合、`CMD`の指定は不要です。

例えば、次のようなDockerfileであれば

```dockerfile
FROM ubuntu
ENTRYPOINT ["echo", "Hello, Docker!"]
```

これをコンテナとして実行した場合、"Hello, Docker!"が常に出力されます。

そのため、Dockerfileでは通常、`CMD`と`ENTRYPOINT`を組み合わせて使用します。それにより、`ENTRYPOINT`で実行するコマンドを固定し、そして`CMD`でデフォルトの引数を設定します。そして、固定のコマンドを実行し、引数を変更せずに実行したい場合には、`ENTRYPOINT`だけを用いると便利です。
初学者がオブジェクト指向について説明してみる。

# 前書き
プログラミングを学ぶ上で必ず通るであろう、オブジェクト指向について自分なりにまとめてみました。
間違っている部分もあるかもしれませんが、読んでいただけると幸いです。
# 目次
　・オブジェクト指向が生まれた背景
　・RPGを例にオブジェクト指向を説明
　・まとめ
 
# オブジェクト指向が生まれた背景
まずは生まれた背景について説明します。テクノロジーの発展によりコンピューターの性能があがり、大規模な開発が可能になり大量のソースコードを書くことが増えました。大量のソースコードと扱う問題点として以下のようなものが挙げられました。

　　・プログラムを一箇所だけ変えたいのに他のコードも合わせて変えないといけない
　　・コードが長く新しいメンバーがわかりずらい
　　・テスト時間が増え開発にコストがかかる

このような問題を解決するために独立性、再利用性、拡張性を持ったオブジェクト指向という考えが広まった。

# RPGを例にオブジェクト指向を説明
オブジェクト指向を一言で表すと「情報空間の概念すべてをオブジェクトと捉え、管理すること」だと思っています。
これだと抽象的で分かりにくいと思うので、RPGを例にオブジェクト指向を説明していきます。

### クラスとは
RPGでキャラクターを作るときのことを考えてください。まずはキャラクターの土台になる人間の設計図を書くと思います。この設計図をことをオブジェクト指向では<font color="LawnGreen">クラス</font>といいます。初期クラスには頭があって、とか足は２本でとか人間である必要条件だけを入れていきます。

### プロパティとメソッドとは
設計図（クラス）に書ける内容として、プロパティとメソッドとがあります。

<font color="LawnGreen">プロパティ</font>というのは、『名前』『年齢』『どこの国出身』『HP』『勝利したときの決め台詞』などのキャラごとの属性のことです。
次に<font color="LawnGreen">メソッド</font>というのは、『攻撃する』『ジャンプする』『決め台詞を言う』などの動き部分つまり処理のことです。

設計図にすべてのキャラクターに共通するプロパティとメソッドの情報を入れることで、初期キャラが完成しました。初期キャラの情報を継承し、勇者や魔法使いといったクラスを増やしていきます。

### 継承
継承というのは初期クラスのプロパティ、メソッドを引き継いだ新たなクラスを作ること。
キャラクターを生成するとき共通した機能をわざわざプログラミングするのが面倒なので、継承を使い開発を楽にしています。

魔法使いを例に継承していきます。
まずはプロパティを変え、HP=100、出身＝ホグワーツ　など魔法使い独自の情報を入れていきます。
次はメソッドを加えます。魔法使いは人間と違って魔法が扱えるので、「攻撃する」といった処理を「魔法を使う」に上書きできます。
このように継承をすることによって、共通のプロパティ、メソッドをまた書かなくてよくなるのでコードの重複を減らしてコードの再利用性、拡張性を高めることができるです。

### 独立性
次に独立性について説明していきます。
先程キャラクターに設定したプロパティのHPは攻撃系のメソッドでしか変えられない値にしましょう。
理由はなにかの拍子に外側から値をいじれてしまったらHPの管理が難しく、コードが管理できなくなるからです。
独立性をもたせることでオブジェクトが与えれる影響や与えられる影響をコントロールすることができます。

# まとめ
オブジェクト指向は独立性、再利用性、拡張性を持つので、今もなお開発に使われています。
至らないところもあると思いますが、オブジェクト指向を理解するきっかけに少しでもなれたら幸いです。
[heroku] Heroku Router 2.0 Public Beta [ひそかに]

[Heroku Advent Calendar 2023](https://qiita.com/advent-calendar/2023/heroku) 23日目、今年もPerfumeはゆかちゃんの誕生日にお送りしています、Salesforceの中の人しょっさんです。毎度ゆかちゃん、誕生日おめでとうございます(n‘∀‘)η ﾔｧｰｯﾎｫｰ

---

Herokuの更新がないな...と思われている方、Changelogはちゃんと追っていますか？
[Heroku Roadmap](https://github.com/orgs/heroku/projects/130)は見ていますか？

pgventor on Heroku Postgresのことですっかり忘れ去られているようですが、少しずつ新しい機能が提供され始めています。

このロードマップ上を見ると`HTTP/2`などもあり、Heroku Routerの更新が始まっているようです。
という中、実は。10月にひっそりと[Heroku Router 2.0](https://devcenter.heroku.com/articles/heroku-runtime-router-2-0)がPublic Betaで公開されています。

まだ提供されている機能は少ないですが、下の方を見てもらうと「HTTP/2」のみならず「IPV6」の表記もあり、これらはRouter 2.0のみで提供されるようです。楽しみですね。

![CleanShot 2023-12-23 at 14.20.28@2x.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/72ab14b0-af92-0b02-0bee-9a629b010529.png)

まだ機能的には少ないですが、Common Runtimeをお使いの方は、次のコマンドを実行するだけで簡単にHeroku Router2.0を利用できます。

```bash
$ heroku labs:enable http-routing-2-dot-0 -a route-2
Enabling http-routing-2-dot-0 for route-2... done
```

順次、新しい機能が提供されていくことと思われますので、これからもHerokuの新しい機能をきっちりと追い続けてください。取り残されないでくださいね、おいてきますよ。新しいHeroku PostgresもRe:inventで発表されたり、ちゃんとこれからもHerokuをよろしくお頼みもうします🙏
【個人的備忘録】Sambaで特定のグループだけがアクセスできるファイルサーバを構築してみた

# 概要
・Sambaによるファイルサーバ構築
・特定のグループ(sambashare)に所属するユーザだけがアクセスできるようにした．
・OS: Ubuntu 22.04.LTS

# Sambaのインストール
```shell
sudo apt update
sudo apt upgrade
sudo apt install -y samba
```

# 設定ファイルのバックアップ
```shell
cd /etc/samba/
sudo cp -a smb.conf smb.conf.default
```

# 設定ファイルの編集
```shell
sudo nano smb.conf
```
# smb.confの末尾に追加
```conf
[share]
   path = /mnt/MyDrive/share
   writable = yes 
   browseable = yes
   valid users = @sambashare
   force group = sambashare
   read only = no
   force create mode = 0660
   force directory mode = 0770
```

# Ubuntuにユーザー追加
```shell
sudo adduser --system --group --no-create-home your-user-name
```
# ユーザをsambashareグループに追加
```shell
sudo addgroup your-user-name sambashare
```
# Sambaのパスワード設定
```shell
sudo pdbedit -a -u your-user-name
```
# Sambaのサービススタート
```shell
sudo service smbd restart
```

# Windowsマシンから接続する例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483686/c18b0e3a-007d-88d9-f355-ab0d6a5c4e7b.png)
・サーバーのipアドレスと共有フォルダまでのパスを図のように指定し，「別の資格情報を使用して接続する」にチェックを入れ，完了をクリック．

・先ほど設定したユーザIDとパスワードでサーバにアクセスできる．
ついにAWS東京リージョンでClaude 2.1 on Bedrockが使えるように!?

AWSの生成AIサービス、Amazon Bedrockでテキスト生成の主力モデル「Claude 2.1」が東京リージョンでも利用可能になったようです！

https://x.com/web_se/status/1738420511632503173?s=20

宇宙最速レポートはひるたさんでした。いつも流石です。


# 現在の状況

マネジメントコンソールを確認すると、確かに東京リージョンでClaudeが新たに選択可能となっています！

![スクリーンショット 2023-12-23 14.08.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/832ec4d8-84a7-f0d7-eb60-c53efaff0edc.png)

ちなみに東京リージョンより先行してClaudeが表示されていたシンガポールリージョンの方は、引き続きUnavailableのままのようです。東京の方が需要高かったのでしょうか？

![スクリーンショット 2023-12-23 14.09.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/7f4f8a8a-096a-d272-8d80-7e5977f25fb8.png)

ちなみにAWS What's Newなどの公式ソースではまだアナウンスされていないようです。
正確な情報は公式ページの動向を引き続き注視いただければと思います。

https://aws.amazon.com/new/?nc1=h_ls&whats-new-content-all.sort-by=item.additionalFields.postDateTime&whats-new-content-all.sort-order=desc&awsf.whats-new-categories=*all

Bedrockの料金ページには日本語版含めてすでに記載がありますが、これは前からかな？

https://aws.amazon.com/jp/bedrock/pricing/

![スクリーンショット 2023-12-23 14.19.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1633856/845f6ca1-0c0d-16d0-3bde-74db7021b67f.png)



# 何が嬉しいの？ これまでと何が変わる？

鳴り物入りでAmazon Bedrockがグローバルにリリースされた2023年9月28日からわずか数日で、AWS東京リージョンにもBedrockが提供開始されていました。

https://aws.amazon.com/jp/about-aws/whats-new/2023/10/amazon-bedrock-asia-pacific-tokyo-aws-region/

ただしこれにはオチがあり、利用可能な生成AIのモデルが先行リージョン（バージニア北部など）と比べてかなり限定されていました。

例えば、多くの人が使うであろうテキスト生成の主力モデルAnthropic Claudeも、Instantという性能重視のコンパクトモデルしか東京リージョンでは使えないという状況でした。

よって、「OpenAIのGPTシリーズ並みに賢いテキスト生成モデルが使いたい！」という日本のAWSユーザーは、メインのアプリケーション自体は東京リージョンで構築し、BedrockのClaudeモデルのAPIだけはバージニア北部リージョンのものを呼び出して使うといったケースが多かったのではないかと思います。

うちもそうでした👇

https://developers.kddi.com/blog/44TMD1pcdiTqR2CMzrdpZo

今回のリリースによって嬉しい点は以下です。

- セキュリティ・ガバナンスの観点でワークロードや通信を東京リージョン内で完結させることができる
- 言語モデルからのテキスト生成結果のレスポンス性能が上がる可能性がある

2点とも、生成AIを活用したアプリケーションをプロダクションで構築している日本のユーザーにとって嬉しいポイントでしょう。


# おわりに

Amazon BedrockやClaudeについてはQiitaのアドベントカレンダー等でも今月、とても盛んに情報発信がなされています。是非みなさんもご覧になさってください！

https://qiita.com/advent-calendar/2023/amazon-bedrock-generative-ai-aws

https://qiita.com/advent-calendar/2023/anthropic-claude
読書感想　プログラムはなぜ動くのか

# 書籍名「プログラムはなぜ動くのか」
著者：矢沢久雄


# 読もうと思った動機
低レイヤー部分の理解を深めるため



# 印象に残った部分

## プログラムが動作するときの各ハードウェアの役割


### メモリ
ディスクからメモリへプログラムを読み込んで実行する。
→ストアド・プログラム方式

#### 物理的な構造
大量に８ビットのデータを格納できる入れ物がある
→配列のイメージ

#### 論理的な構造
型によってバイトを確保する
ポインタを使うとメモリの番地をいじることができる

例

型|バイト数|メモリの個数
---|----|---
char |1バイト|X番地のみ　1個
short|2バイト|X番地~X+1番地　２個
int|8バイト|X番地~X+7番地　８個

#### メモリを効率的に使うにはデータ構造を工夫する
データ構造を工夫することで計算量を減らすことができ、高速化に繋がる。

データ構造名|説明
-----------|-----
配列|物理メモリと同じイメージ
スタック|FIFO。undoなどに使われる
キュー|FILO。動画再生のバッファリング
リスト|配列の要素に、次の要素のインデックスも付与する。データの追加、削除が用意。


#### ヒープ領域とスタック領域

ヒープ領域：
プログラマによって明示的に確保と開放を行う。C++だと　new() delete()
メモリリークの原因になる。            

スタック領域：コンパイラ、OSによって自動生成される領域。プログラマは関与していない


### CPU

演算処理をする部分。

レジスタの集合体である。
レジスタとは
コンピュータの中の部品で「覚えるのが速いけどあんまりたくさんは覚えられない記憶装置さん」のこと

https://wa3.i-3-i.info/word1518.html


### ハードドライブ
非実行時にプログラムを収納する装置
実行時はメモリに読み出す。
メモリの代用として使える仮想メモリという機能がある
windowsではページング方式が使われている
ページングファイル：仮想メモリとなるファイル
ページイン：メモリに読み出し
ページアウト：メモリに書き込み

## ソース・ファイルから実行可能ファイル(.exe)までの流れ

### 処理
名称|説明
---|----
コンパイル|ソースファイルからオブジェクトファイルを作成する処理
リンク|複数のオブジェクトファイルを結合してexeファイルを生成する処理
ダイナミックリンク|dllファイルを連結する。exeファイル実行時に行われる処理



### その他用語

名称|説明
---|----
DLLファイル|様々なプログラムから利用される汎用性の高い機能を収録した、部品化されたプログラムのこと。拡張子.dll
スタティック・ライブラリ|オブジェクトファイルの実体を格納したファイル。拡張子はlib
インポート・ライブラリ|オブジェクトファイルなし。DLLファイルを参照するライブラリ



DLLファイル
https://e-words.jp/w/DLL%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB.html


# 実践できること or 感想


Windowsアプリケーションに携わる時に役立ちそうな知識だと思いました。
ビルド時のエラー調査やexeファイル実行でエラーが発生した時に役立ちそう
（libファイル、dllファイルなど）

webのプログラム（php）ではどうなってるのか調べる。

次回の再読ではChapter1のCPU、Chapter10のアセンブリ言語を掘り下げます。
開発環境のpumaをsystemd経由で自動起動/制御する

## はじめに
開発環境のpumaをsystemdに登録し、systemctlを使って起動・停止などの制御をするようにします。

## 環境
* AlmaLinux 9.3
* Ruby 2.7.8
* Rails 6.1.4.7
* puma 5.5.2
* sd_notify 0.1.1

## sd_notifyのインストール
```ruby:Gemfile
gem 'sd_notify'
```
Gemfileにsd_notifyを追加してbundle installします。

## systemdのユニットファイルを作成
```/usr/lib/systemd/system/puma-app01.service
[Unit]
Description=App01 hosted by puma
After=network.target

[Service]
WorkingDirectory=/path/to/app01
ExecStart=/bin/bash -lc 'bundle exec pumactl start'
User=app01
Group=apps
Type=notify
WatchdogSec=10
Restart=always
Environment=RAILS_ENV=development

[Install]
WantedBy=multi-user.target
```
* WorkingDirectory: アプリケーションルートをフルパスで指定します
* ExecStart: 実行コマンドを指定します（フルパスでの指定が必要ですがbash -lcを挟むことで普段のコマンドに近い形で記述できます）
* User: 実行ユーザーを指定します
* Group: 実行グループを指定します

## 起動・停止など
```
$ sudo systemctl start puma-app01
$ sudo systemctl status puma-app01
$ sudo systemctl restart puma-app01
$ sudo systemctl stop puma-app01
```

## 自動起動設定
```
$ sudo systemctl enable puma-app01
$ sudo systemctl status puma-app01
```

## 参考
* https://github.com/puma/puma/blob/master/docs/systemd.md
【Go言語】echoのAPIをテストする [サーバーを起動させてテスト]



今回はそのテストの中でもサーバーを起動させてテストする方法について書きます


## テスト用にプログラムを用意する

### サーバーの初期化部分を切り分ける

まず、APIのコードは初期状態であれば以下のようになっていると思います。
しかしこのままではテストができないのでまずはテストを行うためにコードを切り分けます。

```go
package main

import "github.com/labstack/echo/v4"

func main() {
    e := echo.New()

	e.GET("/", func(c echo.Context) error {
		return c.String(200, "Hello, World!")
	})

	e.Logger.Fatal(e.Start(":8080"))
}
```

このようにサーバーを初期化する部分を外に切り分けます。
これを行うことで、テスト側でサーバーの初期化を行って起動させることができるようになります。

```go
func InitServer() *echo.Echo {
	e := echo.New()

	e.GET("/", func(c echo.Context) error {
		return c.String(200, "Hello, World!")
	})

	return e
}

func main() {
	e := InitServer()
	e.Logger.Fatal(e.Start(":8080"))
}
```

## テストの作成

テスト側のコードは以下の通りです。順番に説明してきます。

```go
package main

import (
	"io"
	"net/http"
	"net/http/httptest"
	"testing"
)

func TestServerReq(t *testing.T) {
	e := httptest.NewServer(InitServer())
	r, err := http.Get(e.URL + "/")
	if err != nil {
		t.Errorf("Error making request: %s", err)
		return
	}
	defer r.Body.Close()
	if r.StatusCode != 200 {
		t.Errorf("Expected 200, got %d", r.StatusCode)
	}

	body, err := io.ReadAll(r.Body)
	if err != nil {
		t.Errorf("Error reading response body: %s", err)
		return
	}

	if string(body) != "Hello, World!" {
		t.Errorf("Expected 'Hello, World!', got '%s'", string(body))
	}
}
```

### httptest.NewServerでサーバー起動

では`httptest.NewServer`を使うことでサーバーを起動させます。裏でstartが行われるようになっています。Goの場合、ほとんどのライブラリは`net/http`を用いて作成しているためほとんどのライブラリで同様に起動が行えます。

```go
e := httptest.NewServer(InitServer())
```

### リクエストを行う

以下の部分で具体的にリクエストを行っています。変数`r`の中に結果が格納されます。

```go
r, err := http.Get(e.URL + "/")
if err != nil {
    t.Errorf("Error making request: %s", err)
    return
}
defer r.Body.Close()
```

### 検証
その後はテストで検証していきます。ステータスコードのテスト、bodyの内容テストなどをここで行っています。

```go
if r.StatusCode != 200 {
    t.Errorf("Expected 200, got %d", r.StatusCode)
}

body, err := io.ReadAll(r.Body)
if err != nil {
    t.Errorf("Error reading response body: %s", err)
    return
}

if string(body) != "Hello, World!" {
    t.Errorf("Expected 'Hello, World!', got '%s'", string(body))
}
```

### テストを実行

テストを実行すると、無事PASSしました。逆にわざと`Hello, World!`を`Hello, W`に変更したりしてテストした場合はちゃんと失敗してくれたので安心です。

```bash
go test ./...

=== RUN   TestServerReq
--- PASS: TestServerReq (0.01s)
PASS
ok      test    0.333s
```

このようにサーバーを起動するテストはとても簡単に行なえます。これまで苦労してきた人がいたらぜひお試しください。
データベースサーバのインストール 2023

# データベースサーバのインストール

wordpressで使うデータベースサーバの構築をします。
MySQLがOracleに買収されてからしばらくはMySQL使ってたけど、今も現役のようでよかった。
当時の経緯がまとまっていたので、これを読んでよく分かりました。

[MariaDBとMySQL-データベース管理システムの概要](https://kinsta.com/jp/blog/mariadb-vs-mysql/#:~:text=MariaDB%E3%81%A8MySQL%E3%81%AE%E9%81%95%E3%81%84&text=MariaDB%E3%81%AF%E5%AE%8C%E5%85%A8%E3%81%AA%E3%82%8BGPL,%E3%81%8C%E9%AB%98%E3%81%84%E6%80%A7%E8%83%BD%E3%82%92%E8%AA%87%E3%82%8B%E3%80%82)

MySQLのインストールを進めることにしました。
[debianでのMySQLインストール](https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/)

手順としては、Oracleのサイトからrepositoryを追加するdpkgをダウンロードして、インストール


    $ sudo dpkg -i ./mysql-apt-config_0.8.29-1_all.deb
    $ sudo apt update
    $ sudo apt list | grep mysql
    $ sudo apt install mysql-server


ローカルのPCにLinuxをインストールしていた時によく見ていた懐かしいインストール画面が起動し、rootユーザのパスワードを決める。
インストールできたら、とりあえずの接続確認。ほんと、懐かしい！

    debian@temple:~$ mysql -u root -p
    Enter password:
    Welcome to the MySQL monitor.  Commands end with ; or \g.
    Your MySQL connection id is 8
    Server version: 8.0.35 MySQL Community Server - GPL

    Copyright (c) 2000, 2023, Oracle and/or its affiliates.

    Oracle is a registered trademark of Oracle Corporation and/or its
    affiliates. Other names may be trademarks of their respective
    owners.

    Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

    mysql> select version();
    +-----------+
    | version() |
    +-----------+
    | 8.0.35    |
    +-----------+
    1 row in set (0.00 sec)

    mysql> exit
    Bye

これで、MySQLは準備できたので、次PHPの設定が終われば、Wordpressにたどり着けるかな・・・。


P.S.
その後wordpressのインストールは簡単にできました。
一つ注意点があるとしたら、MySQL8系はgrant文でユーザ作成できない点。
wordpressのマニュアルには、grant文でユーザ作っている例がのってましたが、うまく動作せず。

    create user "*****"@"localhost" identified by "**********";
    grant all on *****.****** to  "*****"@"localhost";

な感じですね。
SBI 取引報告書自動取得プログラムを作る

こんにちは、やましょうです。

# SBIの取引報告書
SBIの取引報告書は一括取得できません。
個人であれば、データ共有設定をすれば良さそうですが、
法人の場合は、データ共有はできません。

# 手数料無料で急増する報告書
無料って言うのはいままで１００円とか２００円の利益では放置だったアイテムを
即売買しちゃいます。そのため電子報告書は急増することとなります。
医療費にしろ、なんにしろ、無料っていうのは、がまんせず権利行使しちゃいますよね

# 電子帳簿保存法
2024年1月から電子帳簿取引法がはじまります。
この１個１個のデータを手動で取得するの無理ゲーです。
（マウスでクリックして１個１個とるんです、しかもPDFのファイル名はワケワカメな暗号文です。
そして、日付など検索できなくてはいけません。

ってことでプログラムを作ります。

# プログラムの内容
1.自動log in
2.電子報告書のページに移動
3.上から報告書選択
4.pdf取得（3,4をある限り行う）
5.pdfのファイルを調査、ここから日付を見つけてファイル名全部書き換え
　(pdfのファイル自体は、保護されているため書き換え不可）


 # 動作画面　
<iframe width="560" height="315" src="https://www.youtube.com/embed/x9lGqnu8-WU?si=nR-jv7OCeVRKW6_T" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# このソフトは売れるのか？
謎


以上

やましょうでした。
Railsでreadonly属性が設定されたinputにおいて、プルダウンが操作可能な問題への対処法

※この記事は僕がぶち当たった問題をとりあえずChatGPTくんに丸投げしてライティングしてもらったものです。

# はじめに
Railsアプリケーションでinput要素をreadonlyに設定することは、フォームの入力を無効にし、特定の値を表示する場合などに一般的です。しかし、readonly属性を持つinput要素にもかかわらず、プルダウンが選択できてしまうという問題が発生することがあります。

この記事では、そのような問題が発生した場合の対処法について解説します。

# 問題の再現
まず、問題を再現してみましょう。以下は、readonly属性を持つinput要素とプルダウンが含まれる簡単なフォームの例です。
```erb
<%= form_for @model do |f| %>
  <div class="field">
    <%= f.label :name %>
    <%= f.text_field :name, readonly: true %>
  </div>

  <div class="field">
    <%= f.label :status %>
    <%= f.select :status, options_for_select(['Active', 'Inactive']), {} %>
  </div>

  <%= f.submit %>
<% end %>
```

このコードを実行すると、nameフィールドは正しくreadonlyになりますが、statusフィールドのプルダウンが選択可能なままになることがあります。

# 解決方法
この問題を解決するためには、JavaScriptを使用してプルダウンの操作を無効にする必要があります。以下は、簡単なJavaScriptコードの例です。

```js
document.addEventListener('DOMContentLoaded', function() {
  // nameフィールドがreadonlyの場合、statusフィールドを無効化する
  const nameField = document.getElementById('<%= f.object_name %>name');
  const statusField = document.getElementById('<%= f.object_name %>status');

  if (nameField && nameField.readOnly) {
    statusField.disabled = true;
  }
});
```
このコードは、ドキュメントが読み込まれたときに実行され、nameフィールドがreadonlyの場合にstatusフィールドを無効にします。

これで、inputがreadonlyの場合にプルダウンを選択できないようにすることができます。

# まとめ
この記事では、Railsアプリケーションでinputをreadonlyにした際にプルダウンが選択できてしまう問題に対する解決方法を紹介しました。問題の再現、解決方法の実装、そしてそのまとめとしてJavaScriptを使用した対処法を紹介しました。特定の状況によっては、より詳細な対処法が必要となるかもしれませんが、基本的なアプローチはこの記事を参考にしてください。
ひまわりの咲くご実家 - 最近、Qiitaの記事でとても感動したことがありました。

 # はじめに
最近、Qiitaの記事でとても感動したことがありました。

 # 感銘をうけた記事
@avaiceさんの下記の記事です。

 https://qiita.com/avaice/items/c8a1d3174135b5e8418f

 # どこに感銘したか
感銘というよりは感動に近いものでした。

>皆さんのプログラミングのルーツは何ですか？
私は「日本語プログラミング言語 ひまわり( https://kujirahand.com/himawari/ )」です。

>2023年ももうすぐ終わりですね。年末は実家に帰る人も多いのではないでしょうか。そういうわけで、私のプログラミング人生における実家のような存在 ひまわりを使って、簡単なWebアプリを作ってみました（無理やりすぎる導入）

 いやいやぜんぜん無理やりでないです。記事にコメントさせていただきましたが、@avaiceさんのプログラミング言語へのやわらかい愛着が感じられるとてもすてきな記事ですね。また記事の内容も技術的にもすごいものです。

 # 私のプログラミング人生における実家のような存在
 この表現は心に響きました。わたしにとってはと自問してみましたが、残念ながら日本語プログラミング言語はわたしにとって実家ではないのですが、とてもお世話になった親戚のおうちといったイメージでしょうか？
 でも実家のように考える方はたくさんいらっしゃるのでしょうね。うらやましいです。
 
 # 日本語プログラミング言語を応援しましょう

Mindが生誕してそろそろ40年、次の世代の日本語プログラミング言語ひまわり、TSSが登場して20年くらいが経過したようです。これらの日本語プログラミング言語は非SI現場の開発ツールとしては活用されていると思われますが、SI現場の実装言語としてはまだ弱い立場にあります。

最新の日本語プログラミング言語なでしこ、プロデル、Mindの開発者のみなさまはQiitaのアカウントを持ち、活発に記事投稿コメントをされています。[^1] [^2] [^3]

みんなで日本語プログラミング言語を応援していきましょう！

[^1]: Qiita [まるで詩のような日本語で書いたプログラム - 実際に動きます](https://qiita.com/killy/items/0b5eb530fdceebd8c03e)　参照
[^2]: Qiita [なでしこでもっと美しくFizzBuzzを書く](https://qiita.com/kujirahand/items/4d6a0166f54e4d6290fc)　参照
[^3]: Qiita [日本語プログラミング言語「プロデル」でズンドコキヨシ](https://qiita.com/jpl_produire/items/e28a54709b7eb73cd201)　参照
【Go言語】構造体の基本的な使い方

Go言語でビジネスや開発に役立つソフトウェアを構築する際、**構造体**は重要な役割を果たす。
**構造体**は、プログラムを理解しやすくするための小さな構成要素にプログラムを分解するのに役立つ。

### 構造体の特徴
Goの構造体には次のような特徴がある。

* フィールドをまとめることができる。
* 他の構造体を埋め込むことができるが、アップキャストやダウンキャストはできない。
* 関数の中や式の中でも動的に定義できる。

構造体の基本的な書き方では、**フィールド**の名前と型を定義する。
小文字で始まるフィールド名はプライベート、大文字で始まるフィールド名はパブリックになる。

### 構造体のインスタンス化
Goの構造体をインスタンス化する方法は3つある

1. `new()`関数で作成
1. `var`変数宣言
1. 複合リテラルを使用

#### それぞれの特徴
| 生成方法         | 生成される型                | フィールドの初期値           |
|------------------|-----------------------------|-----------------------------|
| `new()`          | `*Struct`                   | ゼロ値のみ                  |
| var変数宣言      | `Struct`                    | ゼロ値のみ                  |
| 複合リテラル     | `&`をつけると`*Struct`。<br>つけないと`Struct`。 | 初期値を設定できる          |

#### サンプルコード

##### `new()`関数
```go
package main

import (
	"fmt"
)

type Person struct {
	FirstName string
	LastName  string
}

func main() {
	p1 := new(Person)
	p1.FirstName = "Taro"
	p1.LastName = "Yamada"
	fmt.Println(p1) // &{Taro Yamada}
}

```

##### `var`変数宣言

```go
package main

import (
	"fmt"
)

type Person struct {
	FirstName string
	LastName  string
}

func main() {
	var p2 Person
	p2.FirstName = "Hanako"
	p2.LastName = "Sato"
	fmt.Println(p2) // {Hanako Sato}
}

```

##### 複合リテラル
```go
package main

import (
	"fmt"
)

type Person struct {
	FirstName string
	LastName  string
}

func main() {
	p3 := &Person{
		FirstName: "Ken",
		LastName:  "Takakura",
	}
	fmt.Println(p3) // &{Ken Takakura}
}

```


## 参考
https://www.oreilly.co.jp/books/9784873119694/
【UiPath Orchestrator Manager】オンプレ版OCにユーザー作成するときの注意（「列29が見つかりません」エラー対策）

# はじめに
[UiPath Orchestrator Manager](https://marketplace.uipath.com/listings/orchestrator-manager)のユーザー作成時に発生するエラーについて、X（Twitter）以外に発信情報が見つかっていなかったので、記事化しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776370/253fdfbb-28a6-9c9c-58f5-14a28ab726dc.png)
https://x.com/TIM02890958/status/1693797390644592648?s=20

オンプレ版OCのユーザーを作成しようとすると、「列29が見つかりません」と表示されるエラーが発生します。
※ちなみにAutomation Cloud版OCのユーザー作成はOrchestrator Managerではできないので、そもそもOrchestrator Managerでユーザー作成しようとした方は同様のエラーに遭遇したのでないでしょうか

本記事ではその原因と対策について記載します。

# 原因
ワークフロー内の列数設定（30列）が、InputファイルであるExcelファイルの列数（29列）より多いことが原因です（要はプログラム側の問題）。
※Orchestrator Manager2.5.1でもこのエラーは継続中

ワークフローでは以下の箇所でエラーになります。
> UserManager.xaml>Switch (User Operation)>Rename Columns (Create User)>Assign ColumnName (Create User)

列数を指定しているのは、変数「ColumnNames」の規定値です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1776370/3b21912c-255b-104b-eb17-878ba06c6707.png)

InputファイルであるExcelファイルと照合すると、**"EnableMachineLoginUR"という値に該当する列がExcelファイル側にありません（本来Q列にあるべき）**。そのため、列が足りず、また記載した列情報もQ列以降ズレてしまいます。
私が知る限りでは、Orchestrator上でこの設定（URのログイン）をする箇所は見当たりませんし、運用上必要になることもないと思います。

更に、変数「ColumnNames」の規定値とExcelの列を照合すると、もう1つ誤りを発見しました。
**変数「ColumnNames」の"Domain"列と "Type"列が、Excelの列順（B列、C列に相当）と逆**になっています。

# 対策
変数「ColumnNames」の規定値とExcelファイルの列において以下2つの不一致を取り除いてあげる必要があります。
* 変数「ColumnNames」の規定値の"EnableMachineLoginUR"について、Excelファイル側にQ列に相当するものがなく、以降の列もズレてしまう
* 変数「ColumnNames」の"Domain"列と "Type"列が、Excelの列順（B列、C列に相当）と逆

すなわち、変数「ColumnNames」の規定値かExcelファイル（ユーザー.xlsx）の列を修正すればOKです。

 * 変数「ColumnNames」の規定値を修正する場合：
"EnableMachineLoginUR"を削除し、"Domain"列と "Type"列の順序を入れ替える

　または
* Excelファイル（ユーザー.xlsx）の列を修正する場合：
B列「種類」とC列「ドメイン名」を入れ替え、Q列に空列を挿入する

個人的にはExcelファイル修正のほうが楽なのでそちらで実施し、無事にOrchestrator上にユーザー作成をすることができました。

# 最後に
これはOrchestrator Manager側のバグなので、発行元のUiPath修正を待ちたいところですが、オンプレ版Orchestratorでユーザー作成する機会より、Automation Cloudでユーザーを作成する機会が増えていくので、このバグ対策の需要はあまりないかもしれません。Automaion Cloud側のユーザー一括操作方法については、現在調査しているので、判明次第またQiitaに書きたいと思います。
【統計検定準１級】クックの距離を深めに理解する

# はじめに
統計検定を勉強していると突然でてくる「Cookの距離」。そうゆうものね、と使い方だけ理解して読み飛ばせばよいだろうと普通は思うところですが、、、すこし疑問に感じてしまって調べてみたのですがあまり記事がない。ということで、せっかくなので記事に残しておこうと思います。あまりニーズはないかもしれませんが、興味もっていただける方がいらっしゃいましたら「いいね」をいただけると励みになります。

# Cookの距離とは
統計学における回帰分析で使用される診断手法の１つで、データセット内の各観測値が、モデルに与える影響の大きさをを測定するために使われます。

Cookの距離を用いることで、データセット内の影響力の大きな点を識別し、データのクリーニングやモデルの改善を行います。ただし、複数の予測変数を持つ複雑なモデルで有用と言われています（単純なモデルでは、他の方法で外れ値を特定する方が簡単かもしれません）。

また、一般的に、**0.5**や**1**といった閾値以上の観測値が影響力が大きく、**外れ値**とされることが多いですが、実際にはデータのコンテキストと分析の目的に基づいて決定されるべきとされています。


#### 具体的には
ある観測値が除外された場合に、推定される回帰線がどの程度変化するかを示します。

てこ比：$h_{ii}$、標準化残差：$t_i$、観測データ数：$n$ とした時のCookの距離 $D_i$ は、

``` math
D_i= \frac{t_i^2}{p}\bigl( \frac{h_{ii}}{1-h_{ii}} \bigr)
```



# Cook本人が書いた記事がこちら

『Technometrics』という、米国品質協会と米国統計協会によって 1959 年以来四半期ごとに発行されている物理、化学、および工学科学の統計ジャーナル　Vol. 19, No. 1 (Feb., 1977)掲載記事。

https://www.jstor.org/stable/1268249?origin=crossref


# Cookの距離はどのように考えられたものなのか
ここがこの記事のオリジナル部分です。実際にどのような考えのもとCookの距離が考えられたのかをCookが書いた記事をもとに記載していきたいと思います。


- $Y：観測値（n×１ベクトル）$
- $X：説明変数（n×ｐのフルランクベクトル）$
- $\beta：パラメータ（ｐ×1ベクトル）$
- $e：誤差（n×1ベクトル）$

``` math
　このとき、Y=X\beta+e
 ```

- $ここで最小二乗推定量 \hat{\beta} は 、\hat{\beta}=（X^TX）^{-1}X^TY$
- $対応する残差ベクトル R は、 R=Y-\hat{Y}=Y-X\hat{\beta}=（I-X（X^TX）^{-1}X^T）Y$
- $Yの共分散行列 V(\hat{Y})は、V(\hat{Y})=X（X^TX）^{-1}X^T\sigma^2$
- $Rの共分散行列 V(R)：V(R)=（I-X（X^TX）^{-1}X^T）\sigma^2$


今回のような多変量の信頼区間を考えた場合、信頼区間は、信頼楕円体（１次元の場合の信頼区間のようなもの）となります。

この信頼楕円体の方程式は以下の通り。

``` math
\frac{(\beta^＊-\hat{\beta})^TX^TX(\beta^＊- \hat{\beta})}{ps^2} \leq F( p , n-p , 1-\alpha )
```

この左辺が、 $\beta^＊$ と $\hat{\beta}$ の解釈しやすい距離を与えるというのがCookの考えです。
これに対して、$\beta^＊$ に$i$番目を除いたときの $\beta$ の推定値を代入したものを$i$番目のCookの距離といい、式変更を経て以下のように表されます。

``` math
\begin{align}
t_i　&= \frac{Y_i - x_i^{T} \hat{β} }{s\sqrt{1-h_{ii}}} 　とすると\\

D_i　&=　 \frac{t_i^2}{p}\bigl( \frac{h_{ii}}{1-h_{ii}} \bigr)\\
\end{align}
``` 














# PythonでCookの距離を計算するには

統計的モデリングに特化したライブラリである「statsmodels」を利用すれば簡単に計算することができます。なので、導出は難しくても利用するのは簡単です。

https://www.statsmodels.org/stable/generated/statsmodels.stats.outliers_influence.OLSInfluence.html


# まとめ
（だいぶ途中式を省略してしまいましたが）導出を理解することで、Cookの距離がどんなものかについて理解を深めることができました。



# 参考
https://oceanone.hatenablog.com/entry/2021/07/03/001525
「ゴミ箱に捨てる」とrmコマンドの違い

Linuxを勉強したての方がrmコマンドを実行したあとに「どうやって復元するんですか？」と聞いてきたので、そのときに説明した内容を書きます。

## ゴミ箱に捨てる とは

"ゴミ箱に捨てる"とは、コンピューター上でファイルやフォルダを削除する一般的な方法です。

"ゴミ箱に捨てる"では実際にファイルの削除は行っておらず単純にファイルを「ゴミ箱」または「リサイクルビン」と呼ばれる特別な場所に移動しているだけです。ここでは、ファイルは完全には削除されず、一定時間後に削除されるようになっており、基本的にユーザーが必要に応じて復元または永久に削除することができます。

そのためただの移動に過ぎないのです。

## rmコマンドでの削除について

UNIXやLinuxシステムで使われるrmコマンドは、ファイルやディレクトリを永久に削除するために使用されます。rmコマンドによる削除は即座であり、標準的な設定では「ゴミ箱」を経由せずに直接行われます。そのため、rmコマンドで削除されたファイルは通常、復元ができません。逆に言うと速攻削除したい場合には非常に便利です。


## rmコマンドを「ゴミ箱に捨てる」にする方法

デフォルトのrmコマンドを別のコマンドのエイリアスにすることでrmコマンドを「ゴミ箱に捨てる」にすることができます。

### rmtrash のインストール

rmtrashはファイルをゴミ箱に移動させるコマンドです。
Homebrew で rmtrash をインストールします。

```bash
$ brew install rmtrash
```

rmtrash を rm のエイリアスにします。
以下の1行を`.bashrc`や`.zshrc`に追加します。
```bash
alias rm='rmtrash'
```
追加したら設定を読み出します。

```bash
$ source ~/.bashrc
# もしくは
$ source ~/.zshrc
```

これでrmコマンドでゴミ箱への移動がされるようになりました。
令和5年秋IPAプロジェクトマネージャ試験の不合格記録

# 目的
　2023年10月に受験したプロジェクトマネージャ試験の結果が12月21日に発表され、残念ながら不合格になりました。悔しい。。。
2024年もあきらめずに挑戦し続けるために、自分自身の結果と向き合うことで再試験へ向けた備忘録として残したいと思います。不合格対策は各自異なりますので、一部でも参考になれば幸いです。

# 私の現在地
　モノづくり企業に勤める正真正銘おっさんです。組込み系ードウェア設計・開発の経験をバックグラウンドに持ち、ソフトウェア関係は得意ではありません。業務では使用するＩＣのデータシートを読み解き、ソフトウェアエンジニアへ仕様書を発行して技術的な会話はできますが、自分の手で書いたコードを世の中にリリースさせたことはありませんし、ソフトウェアエンジニアとは部署がことなったりアウトソースするため、本当の仕事の仕方は知りません。一般資格としては応用情報技術者試験合格レベルの知識です（2023年春合格）
　年を重ねて、ハード設計から離れてしまい今はプロジェクトマネージャ的な業務に関わっていますが、過去の経験に基づいた仕事のやり方から脱却できず苦労しています。そんな中プロジェクトマネージャ試験なるものの存在を知り、自分の知識の棚卸と、一般知識としてのプロジェクトマネージャを学ぶ機会として本試験に挑戦しました。
 　もう少しプロジェクトマネージャ試験に至った経緯を申しますと、元々は製品開発の関係から情報セキュリティ試験を受け、その流れで応用情報技術者試験を受験したところ運よくどちらも合格したため、それなら高度情報処理試験にも手を出してみようと考えた次第です。

# 試験勉強
　10月実施の試験へ向けて　6月くらいから手を付け始めてました。4ヶ月間の勉強時間はおおよそ120時間でした。平均すると30時間/月となります。実際は、テスト日へ向けて徐々に勉強時間は増えていきましたので、6月時点は　30時間/月よりも少なく、9月は多かったです。

# 試験結果
　試験結果は以下のとおりです。正直午前2の試験が終わった後『え、思っていたのと全然違う。これは落ちたぞ』と思いました。午前2もしっかりと過去問を繰り返ししてあやふやなところはクリアにしておかないと、足をすくわれると思いますので、次回へ向けた反省にしたいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626074/656f9dcd-9b8b-01f7-a095-7a0ea7ca373b.png)

　不合格の要因は午後2の論文です。C判定ということは、問題文の趣旨から逸脱しているということで、まったくダメだったということです。正直言いますと、試験終了後なんとか書ききったので、もしかしたらA判定になるかもとすら思ったものです。恥ずかしい。。。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626074/76accfe8-a0a5-06b5-c622-2a3db1a85743.png)


# 試験対策本
### 対策テキスト①
　プロジェクトマネージャ試験界隈で有名な三好先生のテキストに手を伸ばし、試験の全体像把握に活用。午前と午後2までは何とかなるかなと感じましたが、午後2の論文はプロジェクトマネージャの実際の経験からは書けないと感じましたので、午後2用のテキストの必要性を感じました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626074/87d4be5c-d133-e164-4fd6-cdad80622344.png)

> https://www.amazon.co.jp/gp/product/B0BTGXN7FF/ref=dbs_a_def_rwt_bibl_vppi_i1

### 対策テキスト②
　午後2対策として別テキストを購入して対策を進めましたが、上記テキストの三好先生の方にも書かれていますが、いくつかのテーマ対応するために論文ネタを複数用意しておくという状態まで事前準備出来ている状態まで自分の理解を持っていくことはできませんでした。勉強時間もありますが、不慣れな論文というものに対して理解することが出来ていなかったと感じています。時間を惜しまず、自分の手を動かして何度か論文を書くべきだったと反省しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626074/ae01a9ce-3868-f41d-893a-9c2f956eea41.png)

> https://www.amazon.co.jp/gp/product/B0C5983Y9F/ref=dbs_a_def_rwt_bibl_vppi_i2

 # 2024年秋試験へ向けた対策
　午前２　スキマ時間を使ってしっかりとオンラインの過去問道場を繰り返し実施
　午後１　同じテキストを使って過去問を繰り返して実施し、テストのクセや問われていることを素早く文中から読み取る訓練を実施
 これらを2024年春試験終了後5月より開始する

 論文勉強はしんどいことから目標を決めないと手を付けられない私自身の特性を考慮し、プロジェクトマネージャ試験と同じように論文が求められる2024年春試験システムアーキテクト試験もしくはITストラテジスト試験を申し込み、今の内から論文を始める。（今日から！）
 まだ問題を見たわけではありませんが、システムアーキテクト試験なら、業務の知識＋自分の勉強で知識面はなんとかなるのではないかと、浅はかな考えで選択しようかなと。。。
 問われるテーマは異なると思いますが、論文の骨格となるストーリを1本決める。
 テーマに応じたシナリオを準備する

# さいごに
　残念ながら試験結果は不合格でしたが、学び続けるモチベーションを得たことと、プロジェクトマネージャを体系的に学ぶことで、今の仕事の仕方に対する改善策の方向性は打ち出せるようになったことは非常に大きな収穫です。言い換えるとなぜいままで勉強をしてこなかったのかと後悔をしているくらいです。気づかないうちに長い事努めてきた会社生活の中で、安住を選択してしまっていたのだと非常に後悔をしています。 もし、進捗等を残しておきたくなりましたら、また投稿するかもしれません。
 次回はぜひ合格記録を報告したいです。同じ目標へ向かって取り組んでいる方々と繋がれれば幸いです。
CloudFrontでAPI Gatewayをオリジンに指定する場合の注意

# はじめに
CloudFront経由でAPI Gatewayを叩いてみたくなったので叩きました。
その際のつまづきをメモしておきます。

![cap1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d02e486b-2dd4-59af-db00-bed4f7897da1.png)


### 1.HOSTヘッダーをオリジンAPI Gatewayにリクエストしてエラー
###### エラー内容
```
< HTTP/1.1 403 Forbidden
~（略）~
{"message":"Forbidden"}
```
ステータス403で上記レスポンスが返却されました。

###### エラー原因
https://qiita.com/folky_records/items/2a231b14c08be82a183a

↑記事でも詳しくまとめられていますが、API Gatewayがオリジンの場合、Origin Request PolicyでHostをオリジンへリクエストするよう設定すると、このエラーが発生するようです。

![cap2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/4321cc21-2728-945b-a274-ee33f5ac3775.png)

CloudFrontの設定画面でも、API GatewayへのOrigin Request PolicyはAllViewerExceptHostHeader（HOSTヘッダー以外をオリジンへリクエストするOrigin Request Policy）が推奨されています。

![cap3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/eb010a6b-3e53-889c-9c3d-757bad500d29.png)


### 2.オリジンパスとオリジンへのリスエストパスの関係を誤解してエラー
###### エラー内容
```
< HTTP/1.1 403 Forbidden
~（略）~
{"message":"Missing Authentication Token"}
```

###### エラー原因
CloudFrontはパスパターンを確認した後、そのパス部分を**すべて**含むリクエストをオリジンに送信する仕様でした。（そりゃそうか）

パスパターン設定とcloudfrontからオリジンへのリクエストパスの関係は以下の通りとなります。

パスパターン設定

![cap4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/d32871fa-efb5-d828-36a5-ce093a1832ea.png)


リクエストパス
```
// デフォルトパスパターンに一致するケース
https://XXXXX.cloudfront.net/aaa
  → 〇：https://expressEC2instace/aaa // 想定通りの挙動

// パスパターン	/api/*　に一致するケース
https://XXXXX.cloudfront.net/api/example
    // なんとなくパスパターン以降がパスとなると想定していた
  → ☓：https://apigateway_dev/example
    // オリジンへはパスパターン込みでリクエストされる
  → 〇：https://apigateway_dev/api/example
```

つまり、API Gatewayのメソッドを以下のように作成する必要があります。

![cap5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3654730/b915fd5d-e1ec-6e9a-6490-a22a471118a8.png)


API Gatewayのパス設計がCloudFrontのパスパターンを考慮しないといけないのはなんか微妙ですね・・・

# おわりに
単純なエラーだったので良かったですが、API Gateway周りは微妙に不親切なことが多いように思います。
これからも触れる機会を作っていき、慣れていきたいです。

また、見聞きしたことのあるようなよくある構成でも、実際にやってみないと分からないことは多くあると強く思いました。
少しでも気になったら手を動かす癖がつけばいいなと思います。
RAID 1とLVMを組み合わせたストレージ構成の理解と実装

# RAID 1とLVMを組み合わせたストレージ構成の理解と実装

## 導入
ストレージの冗長性と柔軟性は、データの安全性とシステムの運用効率にとって非常に重要です。この記事では、2つのハードディスクをRAID 1とLVMで構成する方法とそのメリットを解説します。RAID 1はデータの冗長性を、LVMはストレージの柔軟な管理を提供します。この組み合わせにより、効率的かつ堅牢なストレージシステムを実現できます。

## RAID 1とは
RAID 1は、2つ以上のディスクに同じデータをミラーリングすることで冗長性を確保するシステムです。一方のディスクが故障しても、もう一方に完全なデータのコピーが残るため、データの損失リスクを大幅に減らすことができます。

## LVMとは
LVM（Logical Volume Manager）は、複数の物理ディスクを柔軟に管理するシステムです。物理ディスクを論理ボリュームに抽象化し、容易なリサイズやデータの移動が可能になります。これにより、ストレージの容量を動的に調整し、システムの要件に応じた最適なストレージ構成を実現できます。

## RAID 1とLVMの組み合わせ
RAID 1とLVMを組み合わせることで、データの冗長性とストレージの柔軟性を同時に確保できます。ここでは、AとBのハードディスクをRAID 1とLVMで構成する際のフローを説明します。

### ステップ 1: RAID 1アレイの設定
1. **ハードディスクの準備**: AとBのハードディスクをシステムに接続します。
2. **RAIDアレイの作成**: `mdadm`ツールを使用して、AとBのディスクからなるRAID 1アレイを作成します。
3. **RAIDアレイの構築**: AとBに同じデータをミラーリングし、冗長性を確保します。

### ステップ 2: LVMの設定
1. **物理ボリュームの作成**: RAID 1アレイを物理ボリュームとしてLVMに登録します。
2. **ボリュームグループの作成**: 作成した物理ボリュームを含むボリュームグループを作成します。
3. **論理ボリュームの作成**: ボリュームグループ内に論理ボリュームを作成し、ld1とld2という名前を付けます。

### ステップ 3: データの使用と冗長性の維持
1. **ファイルシステムの作成とマウント**: 論理ボリュームにファイルシステムを作成し、使用可能にします。
2. **データの読み書き**: データはRAID 1アレイを通じて論理ボリュームに書き込まれます。RAIDは物理ディスクにデータをミラーリングし、LVMはその上の論理的なストレージレイヤーを管理します。
3. **ディスクの監視と管理**: RAIDアレイとLVMの状態を定期的に監視し、問題が発生した場合は迅速に対応します。

## 結論
RAID 1とLVMを組み合わせることで、データの安全性を確保しながら、ストレージの管理をより柔軟に行うことができます。この構成は、効率的かつ堅牢なストレージシステムを必要とするあらゆる環境に適しています。適切な計画と知識をもって実装すれば、データの損失リスクを最小限に抑えつつ、成長するストレージ要件に対応することができます。
ChatGPTと学ぶQ学習

OpenAIのQ*(Qスター)というAGIのプロジェクトにQ学習が関係しているのではないかと噂されています。そこで、ChatGPTとQ学習について学んでみました。

# イントロダクション
Q学習は、強化学習の一種であり、エージェントが環境と相互作用しながら最適な行動を学習する方法です。Q学習の目的は、エージェントが環境内で最適な行動を選択し、最大の報酬を得ることができるようにすることです。つまり、毎回の行動と結果を見て、どの行動がいい結果につながるのかを学びます。たとえば、右に進んだら報酬がもらえたら、次回も右に進むように調整します。用語については次の章で解説します。

# 強化学習の基本概念
マリオで例えるとわかりやすいです。
- エージェント: マリオ（プレイヤーが操作するキャラクター）
- 環境: マリオのゲームステージ（敵キャラクターや障害物が配置されたマップ）
- 行動: マリオが取ることができるアクション（例: 左に移動、右に移動、ジャンプ、ダッシュ）
- 報酬: マリオがゲーム内で得られるポイントやアイテム（例: コインを取る、敵を倒す、ゴールに到達する）
- 状態: マリオの現在の位置や状況（例: ステージのどの位置にいるか、大きさやパワーアップの状態、残り時間）

# Q学習のアルゴリズム
### アルゴリズム概要
1. **マリオの行動選択:**
マリオがある状態において、Qテーブルから最も高いQ値を持つ行動を選択します。例えば、「右に移動」が最適と判断されたとしましょう。

2. **行動の実行:**
マリオが右に移動します。

3. **報酬の取得:**
マリオが右に移動した結果、新しい状態に遷移し、報酬が得られます。例えば、コインを取得するとポジティブな報酬を得たとします。

4. **Q値の更新:**
Q値の更新式を用いて、Qテーブルの対応するセルが更新されます。
更新式：
``` math
Q(s, a) = Q(s, a) + \alpha \cdot \left( R + \gamma \cdot \max(Q(s', a')) - Q(s, a) \right) 
```
ここで、現在の状態(s)、「右に移動」の行動(a)に対応するQ値が更新されます。
5. **次の行動の選択:**
更新されたQテーブルを参照して、次の状態での最適な行動を選択します。

このサイクルを繰り返すことで、マリオは試行錯誤を通じて最適な行動を学習していきます。エージェントが環境と対話するたびにQ値が更新され、最終的に最適な行動を見つけるようになります。


### QテーブルとQ値の更新式について
Q学習では、エージェントは状態(State)と行動(Action)の組み合わせに対してQ値と呼ばれる価値を持ち、これを学習していきます。Qテーブルはこれらの状態と行動に対するQ値を保持する表です。例えば、(マリオの位置(状態): 画面の中央, 行動: 右に移動)というセルには、その組み合わせに対するQ値が格納されます。

更新式は前述した通り以下の式です。
``` math
Q(s, a) = Q(s, a) + \alpha \cdot \left( R + \gamma \cdot \max(Q(s', a')) - Q(s, a) \right) 
```

- $Q(s, a) $: 現在の状態 \( s \) と行動 \( a \) に対するQ値
- $\alpha$: 学習率（0から1の間の値）。新しい情報をどれだけ重視するかを制御します。
- $R$: 現在の行動によって得られる報酬
- $\gamma$: 割引率（0から1の間の値）。将来の報酬をどれだけ重視するかを制御します。
- $\max(Q(s', a'))$: 次の状態 \( s' \) において取りうる全ての行動に対するQ値の最大値

この更新式の理解にはいくつかのポイントがあります：

1. **新しい情報の統合：** 第二項の$R + \gamma \cdot \max(Q(s', a'))$ は、新しい情報を表します。これは、現在の行動によって得られる即時の報酬 \( R \) と、次の状態 \( s' \) において取りうる全ての行動に対するQ値の最大値を考慮しています。

2. **過去の知識の維持：** 第一項の$Q(s, a)$は、エージェントがすでに知っている情報です。学習率$\alpha$を介して、新しい情報と過去の知識をどれだけ混ぜるかを制御します。

3. **目標の設定：** Q学習の目標は、Q値を適切に更新して最終的に最適な行動を見つけることです。これは未知の状態においても適切な行動を選ぶ能力を向上させることを意味します。

この更新式を用いて、エージェントは試行錯誤を通じて最適な行動を学習していきます。

# Q学習のメリットと制約
### メリット
- モデルフリー
Q学習はモデルフリーな手法であり、環境に対する事前の知識が必要ありません。これにより、複雑な環境や実世界の問題にも適用可能です。
- オンライン学習が可能
オンライン学習とは、エージェントが新しいデータを逐次的に学習し、即座に行動を更新できる能力のことで、Q学習はそれを可能にしています。

### 制約
- 大規模な状態空間への対応
Q学習はQテーブルを使用して状態と行動の組み合わせに対するQ値を保持します。大規模な状態空間では、膨大な数のセルが必要になり、メモリの消費や計算量の増加が課題となります。

- 探索と活用のトレードオフ
Q学習では探索と活用のバランスを取ることが重要です。探索が不足すると最適な行動を見逃し、逆に探索が過剰になると効率が悪くなります。

- 適切な報酬の設計
Q学習の成功は報酬の設計に大きく依存します。報酬の与え方が不適切だと、エージェントは望ましくない行動を学んでしまう可能性があります。

- 非定常な環境への対応
環境が変化する場合、Q学習は収束に時間がかかるか、最適な戦略を見失うことがあります。これに対処するためには、適応的な手法が必要です。

これらの制約に対処するため、Q学習の発展形や他の強化学習アルゴリズムが提案されています。例えば、関数近似法や深層学習を組み合わせることで、大規模な問題にも対処できる手法が提案されています。

# まとめ
Q学習は人間のように試行錯誤することで、ゲームが上達していくようなイメージでした。AGIは人間のような知能を指しますので、Q学習が取り入れられているという話は妙な納得感があります。けっこう様々な課題・制約がありますが、OpenAI社はどのように解決したのでしょうか。今後のニュースが楽しみですね。
dockerで立ち上げたRails7アプリにホットリロードを導入する

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー19日目です。

今回は、Railsアプリにホットリロード機能を導入します。

### ホットリロードとは？
Web制作などでviewを変更した場合、変更をブラウザで確認するには一度リロードする必要があります。

ホットリロードとは、コードの変更を自動で検知し、リアルタイムに変更した内容をブラウザ側に反映できることを指します。

# Turbo Streamを利用したホットリロード機能の導入

Railsでホットリロードを実現するには様々な方法があります。今回は、以下のgemを利用します。

https://github.com/kirillplatonov/hotwire-livereload

このgemを利用するためには、`redis`を導入する必要があります。

なので、まずはDockerで立ち上げているアプリにredisを導入します。

以下のようにdocker-compose.ymlにredisのサービスを設定します。

:::note info
以下のdocker-compose.ymlは例であり、サービス名などは適当です。
:::


```diff_yaml:docker-compose.yml
version: '3.8'
services:
  iscroll-db:  # サービス名を変更
    image: mysql:8.0.32
    command: --default-authentication-plugin=mysql_native_password
    container_name: iscroll-db  # コンテナ名を変更
    ports:
      - 4306:3306
    volumes:
      - iscroll-db:/var/lib/mysql  # ボリューム名も変更できます
    environment:
      MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
      TZ: Asia/Tokyo
    security_opt:
      - seccomp:unconfined
  i-scroll-web:
    tty: true
    stdin_open: true
    container_name: i-scroll-web
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - .:/i-scroll-web
      - bundle:/usr/local/bundle
      - public-data:/i-scroll-web/public
      - tmp-data:/i-scroll-web/tmp
    command: bash -c "rm -rf tmp/pids/server.pid && bin/dev"
    environment:
      TZ: Asia/Tokyo
    depends_on:
      - iscroll-db  # 依存関係のサービス名を更新
+     - redis
    ports:
      - 3000:3000
+ redis:
+   image: redis:latest
+   container_name: redis
+   ports:
+     - 6379:6379
volumes:
  iscroll-db:  # ボリューム名も変更できます
    driver: local
  bundle:
    driver: local
  public-data:
    driver: local
  tmp-data:
    driver: local

```

続いて、Gemfileのdevelopmentブロックの中にgemを記載します。

```ruby:Gemfile
gem 'hotwire-livereload'
```

Gemfileを編集したアプリのディレクトリ内で`bundle install`を実行

```bash:ターミナル
bundle
```

同ディレクトリにて、以下のコマンドを実行します。すると、以降rails sでサーバを立ち上げている時はホットリロードになっています。

```bash:ターミナル
rails livereload:install
```

詳細は、GitHubのreadmeを覗いてみてください。

https://github.com/kirillplatonov/hotwire-livereload

# おわりに
ホットリロード、とても便利ですね！
Terraformを用いたAzure IoT Hubのデバイス作成

# 初めに
Terraformを用いてIoTHubのデバイスを構築する一例を紹介します。

## IoT Hubとは？
IoT Hubは、Azureが提供するフルマネージドサービスで、大量のIoTデバイスからのメッセージを安全に収集し、それらを管理するためのソリューションです。これにより、デバイス間通信、デバイスの管理、セキュリティ対策などが可能となります。

https://learn.microsoft.com/ja-jp/azure/iot-hub/iot-concepts-and-iot-hub

## デバイスとは？
デバイスとは、IoT Hubに接続されるセンサー、アクチュエータ、組み込みデバイス、ゲートウェイなどの物理的または仮想的なエンティティを指します。これらのデバイスは、様々な種類のデータを生成し、IoT Hubに送信することができるほか、IoT Hubからのコマンドを受け取ってアクションを実行することが可能です。

デバイスの主な特徴:
１．ユニークなID: 各デバイスはIoT Hubに登録される際に、一意のID（デバイスID）を割り当てられます。これにより、IoT Hubは個々のデバイスを識別し、セキュアな通信チャネルを確立できます。

２．セキュリティ: デバイスは、対称キー、X.509証明書、またはトークンベースの認証を使用してIoT Hubに安全に接続します。これにより、データの機密性とデバイスの完全性が保護されます。

３．デバイスツイン: 各デバイスにはデバイスツインがあり、これはデバイスのメタデータ、構成、状態情報をクラウドと同期するためのJSONドキュメントです。デバイスツインは、デバイスがオフラインの間にもクラウド側で変更を行い、デバイスが再接続した際に同期することを可能にします。

４．ダイレクトメソッド: IoT Hubは、ダイレクトメソッドを介してリアルタイムでデバイスに対してリモートプロシージャコール(RPC)を行うことができます。これにより、即時のアクションをデバイスに命令することができます。

５．メッセージング: デバイスはセンサーからの読み取り値や計算結果などのデータをメッセージとしてIoT Hubに送信でき、また、IoT Hubからデバイスへのコマンドや設定変更などもメッセージとして受信可能です。

６．デバイス管理: IoT Hubを通じて、デバイスのファームウェア更新や構成変更、リモート監視などの管理タスクを行うことができます。

７．スケーラビリティ: IoT Hubは数百万台のデバイスをサポートする設計となっており、大規模なIoTソリューションを実現するためのスケーラビリティを備えています。


# 実装内容
Terraformの公式ドキュメントを確認したのですが、IotHubのデバイスの作成はTerraformでは未対応のようです。

https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/iothub

なので、Terraform内にaz commandを実行できるように実装しました。

```bash

resource "azurerm_iothub" "example" {
  name                = "exampleIothub"
  resource_group_name = azurerm_resource_group.example.name
  location            = azurerm_resource_group.example.location

  sku {
    name     = "S1"
    capacity = "1"
  }

  tags = {
    purpose = "testing"
  }
}

resource "null_resource" "extension_install" {
  provisioner "local-exec" {
    command = "az extension add --name azure-iot"
  }
}


resource "null_resource" "device_create" {
  depends_on = [null_resource.extension_install]

  provisioner "local-exec" {
    command = "az iot hub device-identity create --device-id <デバイス名> --hub-name ${azurerm_iothub.example.name}"
  }
}
```
2023年 気まま と Power Automate と わたし（前編）

:::note info
この記事は、[Power Apps Advent Calendar 2023](https://qiita.com/advent-calendar/2023/advent-calendar/2023/powerapps) 12月25日担当分の記事です。
:::
こんにちは、[たな](https://twitter.com/dreams_panda) です。
Qiita Advent Calendarへの参加ということで、Qiitaで記事を書いていこうと思います。

アドベントカレンダーもいよいよ最終日となりました。
最終日となる今日は、私が主催しているコミュニティである「気ままに勉強会」と「Power Automate」とどのようにかかわってきたか20223年の振り返りたいと思います。

※ 2022年も同様のテーマで振り返えった記事は以下となります。

https://tana-techlog.net/?p=956

:::note info
「[気ままに勉強会](https://kimamani.connpass.com/)」は、Power Automate 主にクラウドフローを中心とした勉強会です。
しかし、連携することの多いMicrosoft 365サービスであったり、Power Platformの仲間たち、あるいは、一見関係なさそうに見えるけど、Power Platformを学ぶ際に役に立つと思われる題材であれば、なんでもテーマにして、みんなでスキルアップしていこうという会です。
:::


# 「気ままに勉強会」で扱ったテーマ
2023年の気ままに勉強会は、#41～#73 まで全32回開催いたしました。
2022年とはちょっと違ったことを行ってみようという目標があったのですが、達成できたかなと思っています。
参加されたメンバーの方がどのように感じられたかはぜひお伺いしてみたいですね。

メインで行ったイベントがどのような内容だったかは、運営メンバーの[ようさん](https://twitter.com/Yo_8One)のまとめをご覧ください。
<br>
＜2022年1月～3月＞

https://yo-yon.hatenablog.com/entry/powerautomate20231202

日頃からお世話になっているMicorosoft MVPの先輩方々に気ままに勉強会で初登壇いただいたのが印象深かったです。
[河村さん](https://twitter.com/LeffeLove)、[優吾さん](https://twitter.com/yugoes1021)、[りなたむさん](https://twitter.com/Rinatamu_ITDR)、[やまさん](https://twitter.com/yamad365) ありがとうございました！2024年もよろしくお願いいたします。（登壇をねｗ

<br>
＜2022年4月～6月＞

https://yo-yon.hatenablog.com/entry/powerautomate20231204

運営LT、テーマLTなど昨年までと違う形でのLT会も開催してみました。
どちらも共通のテーマで複数人の方にお話ししていただく形で、登壇者の方によって内容がこんなに変わるんだというのも楽しかったですね。1回で4度美味しい会でした。

<br>
＜2022年7月～9月＞

https://yo-yon.hatenablog.com/entry/powerautomate20231206

Power Automate1（クラウドフロー）が中心の気ままに勉強会ですが、DX推進のお話だったり、Power Apps寄りなお話、Dataverseなんてキーワードも出てきたちょっと変化球な期間でした。
いろいろな角度からみるPower Platformはいかがでしたでしょうか。私は楽しかったです。

<br>

＜2022年10月～12月＞

https://yo-yon.hatenablog.com/entry/powerautomate20231208

座談会形式で、Power Platform relase wave2 planやMicorosoft Ignite 2023の振り返りといった試みもしました。やっている運営メンバーは楽しいのですが、参加されたメンバーの方々にも楽しんでいただけていたら幸いです。

そしてなんといっても「気ままに勉強会」は、2021/11/20から開始し、おかげさまで2周年を迎えることができました。
昨年は、特別会として一周年記念イベントを実施しましたが、今年は、「Weekly News Offline ～2023年 冬の陣～」は、4コミュニティのコラボイベントでかつ初のオフライン（オンサイト）でのイベント開催させていただくこととなりました。

https://pp-weeklynews.connpass.com/event/300026/


![2023_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1382111/31093c12-fc3e-f42f-44e6-811aaa55cbd1.png)

「気ままに勉強会」では、おわりの会という枠で、Power AutomateのUpdate情報の紹介をするコーナーがちょこっとだけあります。Update情報が中心の他のコミュニティとは異なりますがお仲間にいれていただきました。
<br>

私は、コミュニティへの参加がオンラインから始まっているので、オンサイトイベントの経験がありません。
そのため、オンラインでしかお会いできていなかったメンバーの方と直接お話しできて、とても嬉しかったです。
2024年も何かしらのタイミングでオンサイトイベントやりたいですね。
<br>
社外コミュニティ初登壇してくださった方のご紹介やそのほかの振り返りは、「[2023年 気まま と Power Automate と わたし（後編）](https://tana-techlog.net/?p=1187)」に綴っていこうと思います。

※ 後編の記事の方でも、よかったよ、役に立ったよという方は、こちらのQiitaの記事の方にいいね！をよろしくお願いします。