OmniAICreator/Qiita-1.07M huggingface dataset:
【生成AI】文化庁の著作権セミナーに参加してみた

文化庁から、生成AIを絡めた一般人向けの著作権セミナーが開かれていたので参加してみました。

※筆者は、AIの学習済みモデル開発をしたり、何か創作をするような立場でもない一般人です。
　また、著作権の存在こそ知っているものの、詳細に把握しているわけではないため、誤った解釈をしている場合があります。

# 講演資料及び動画
https://www.youtube.com/watch?v=eYkwTKfxyGY
https://www.bunka.go.jp/seisaku/chosakuken/93903601.html

# 感想
※いろんな人に見てほしいセミナーだと思っているので、セミナーの内容については掘り下げません。上のURLからご自身で視聴してください。
- 生成AIの利用等に関係なく、著作権に詳しくない人は教育目的で視聴しておいた方が良いと感じた。
    - 情報発信がしやすくなった時代なので、ささいなコンテンツ発信という行動から著作権という法律と触れ合う機会は間違いなく増えているはずなのに、著作権って結局なにする法律なの？という理解が無いケースは少なくないはず。
- 昨今成長目まぐるしいAIに向けて、ここ1年以内に何か新しい法律が定められてそれを紹介する！みたいなことはない。
    - いままで発信し続けていることの整理をして、分かりやすく発信しているセミナー。
- 生成AIを利用する人も、AI開発に用いるデータセットに含まれる著作物を作成する人も、求めているのは法律に反するかの線引きが事前にできるガイドラインとかルールブックみたいなものでは？と思う。
    - ただし、法律に基づいて線引き（司法判断）をするのはあくまで裁判所。行政機関である文化庁としては、そのラインは曖昧にしておいて、悪いことができないように抑止するようなスタンスを取るべきだと思うので文化庁にそれを求めても仕方がない気がする…。
    - そういった判断を前例に基づいて的確にできるようにするには、裁判所の判例が増えていく必要がある？
- 著作権侵害の判断点となる類似性における「ありふれた表現であるか？」という部分は、今後の生成AIの発達次第では、今私たちが感じている「ありふれた表現」という概念が変わるということが起きそうな気がした。
    - 例：「とてもきれいな絵だけど、AIが生成しそうな絵だね」など。

# 見ながらとっていたメモ（読まなくてOK）

<details>
<summary>メモ</summary>

- 著作権侵害には、類似性があり、依拠性があるか？という判断
    - 類似性
        - 共通した部分が、表現なのか？アイディアや事実なのか？
        - 創作性がある表現なのか、ありふれた表現なのか？
    - 依拠性
        - 依拠：既存著作物に触れた（見る知る聞く）うえで、自己の作品にそれを取り入れていること
        - 制作時に既存著作物の表現を知っているか
        - 既存著作物と同一しているか
        - 後発作品の制作経緯
            - 依拠せず制作したことを合理的に説明できるか
            - 説明を求められるのは、著作権侵害の被疑者側
- AIと著作権は段階をおいて判断
    - AIの開発や学習段階
        - 学習データを収集し、データセットを作る
        - 学習プログラムを利用し、学習済みモデルを制作する
        - 複製、譲渡＆公衆送信
            - データセットのスクレイピング収集
            - 学習データセットの公開
            - 権利制限規定整備により、著作権法第[三十条の四](https://elaws.e-gov.go.jp/document?lawid=345AC0000000048)導入


>（著作物に表現された思想又は感情の享受を目的としない利用）
第三十条の四　著作物は、次に掲げる場合その他の当該著作物に表現された思想又は感情を自ら享受し又は他人に享受させることを目的としない場合には、その必要と認められる限度において、いずれの方法によるかを問わず、利用することができる。ただし、当該著作物の種類及び用途並びに当該利用の態様に照らし著作権者の利益を不当に害することとなる場合は、この限りでない。
一　著作物の録音、録画その他の利用に係る技術の開発又は実用化のための試験の用に供する場合
二　情報解析（多数の著作物その他の大量の情報から、当該情報を構成する言語、音、影像その他の要素に係る情報を抽出し、比較、分類その他の解析を行うことをいう。第四十七条の五第一項第二号において同じ。）の用に供する場合
三　前二号に掲げる場合のほか、著作物の表現についての人の知覚による認識を伴うことなく当該著作物を電子計算機による情報処理の過程における利用その他の利用（プログラムの著作物にあつては、当該著作物の電子計算機における実行を除く。）に供する場合

- 「享受」が目的でないなら著作権の権利制限規定に沿った利用となる
	- AIの学習用データセット作成のための収集や作成、学習済みモデルの開発など
	- 不当に利益を害する場合は適用外。
	- 将来の潜在的販路を阻害するか？という点から、最終的には司法判断。
- 生成、利用段階
	- 人が絵を描いたりするケースと同じで、類似性と依拠性の判断をする
		- AIだから俺のせいではない、という言い逃れができない
	- 私的使用の複製に該当する、生成は権利制限規定に該当して許諾なく実施可能
	- 公表、販売などをする場合は、利用許諾が必要。
	- 議論は、「依拠性」
		- 著作物が学習に使われているか？
		- 生成物が元の表現と類似しているなら推定できるのでは？
		- 独自創作であるといえないなら依拠性があるといえるのでは？
		- ここは最終は司法判断
		- 検討事項
			- 既存著作物認識していて、類似物を生成した時
			- i2iで入力しているとき
			- 集中学習させたAIを使っている（LoRAなど？）時と、そうでない時で、依拠性の考えが変わるか
- 利用者の対応はどうするべきか
	- 利用行為が、権利制限規定に該当するかを確認する
	- 既存著作物と類似性のあるものを生成していないか
		- 生成物を使うなら、
		- そのまま利用することを避ける
		- 既存著作物とことなるものになるように大きく修正を入れる
		- 利用許諾を得る
- AI性生物は著作物なのか、著作者は誰か
	- コンピュータ創作物が著作物なのかの検討
		- AIが自律的に生成したものは、思想や感情を創作的に表現していないと考える
		- 人からプロンプト入力がない、または簡易的な入力である時
	- AIを道具として利用しているか？は、創作的意図と創作的寄与があるか？が判断基準となる

</details>
【Java】タスクの遅延実行～ScheduledExecutor～

Javaでタスクの遅延実行体験レシピ

使用するのはScheduledExecutorServiceのscheduleメソッドです。

①インスタンスの生成
Executorクラスのファクトリメソッドを使用してScheduledExecutorServiceのインスタンス生成します。
```java
ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
```
②遅延実行させる処理をScheduledExecutorServiceのscheduleメソッドで指定
今回はコンソールにfinishと表示し、スレッドプールを終了させるラムダ式を１秒間遅延させて実行させます。
```java
	System.out.println("finish");
			exec.shutdown(); //スレッドプールを閉じる
		},1,TimeUnit.SECONDS);
```
③完成コード＆実行結果
以下の例では、while文で0.1秒ごとに秒数を出力し続け、execスレッドがShutdownしたら実行を終了するという処理を付け加えてます。
```java
class Main {
	public static void main(String[] args) {
		//インスタンスの生成
		ScheduledExecutorService exec = Executors.newSingleThreadScheduledExecutor();
		exec.schedule(() -> {
			System.out.println("finish");
			exec.shutdown(); //スレッドプールを閉じる
		}, 1, TimeUnit.SECONDS);
		int count = 0;
		while (true) {
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO 自動生成された catch ブロック
				e.printStackTrace();
			}
			if (exec.isShutdown()) {
				break;
			}
			System.out.println((++count) * 100 + " ms");
		}
	}
}
```
新しいスレッドが生成＆実行されるものの１秒間待機し、その間に100,200,300...とカウントアップ
そして１秒間経過したタイミングでコンソールに「finish」と表示され、execスレッドがシャットダウン。
それにより、while文もbreakとなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3484672/9447e5d3-7033-a55a-6043-1dfcb334913d.png)
[Vuetify]入力フォームでValidationエラー時はログイン処理を投げないようにする

- Vuetify3を使ってログインフォームを構築しています。
- Validationエラーが発生しているときはログイン処理の関数を呼び出さないようにします。
- 認証エラー前の制限をかけることで通信回数を減らします。

## 目次
- コードと解説
- おわりに

## コードと解説
さっそく、どのように実現するか見ていきましょう。Vuetifyはv3を使用していることに注意してください。

以下の記述は画面部分です。ログイフォームを表現しています。
このとき、v-formコンポーネントのrefでValidationエラーを検知しています。
v-form コンポーネントは Vuetify の一部であり、入力要素のバリデーション（validation）をサポートしている。そのため、ref 属性を使用してフォームに参照を作成することで、コンポーネント内のメソッドやデータから直接フォームにアクセスし、バリデーションをトリガーしたり、バリデーションの結果を取得することができるので、それを利用する。

```vuejs:template
  <v-card-title class="text-center">ログイン</v-card-title>
  <v-form :lazy-validation="true" ref="form">
    <v-text-field v-model="email" label="メールアドレス" :rules="emailRules"></v-text-field>
    <v-text-field v-model="password" label="パスワード" type="password" :rules="passwordRules"></v-text-field>
  </v-form>
  <v-card-action class="d-flex">
    <v-btn class="mx-auto my-2" color="primary" @click="onLogin">ログイン</v-btn>
  </v-card-action>
  </v-card>
```
以下の記述は処理部分です。methodsにログインボタンをクリックした時の処理を書いてあげます。formの中身をみて、trueならバリデーションエラーは起きていないので、if文の中のlogin関数を実行できます。
```typescript:script lang="ts"
  methods: {
    async onLogin() {
      let e
      try{
        const form: any = this.$refs.form
        const { valid } = await form.validate()
        if (valid) {
        const response = await this.controller.login(this.email, this.password, this.presenter)
        }
      } catch (e) {
        console.log("エラー")
      }
    }
  }
```
これで、入力フォームでValidationエラー時はログイン処理を投げないようにすることができました。
ログインボタンを押しても、処理自体を止めているので認証エラーも起きません。

![スクリーンショット 2023-06-28 22.31.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/40e3d8ff-1ed1-9977-604b-c9ba1ae3fbd8.png)


## おわりに
Validationエラーが出ている時は、ボタンを非活性化して押せないようにすると、より良いですね。。。
git hubのリポジトリにフォルダを追加

## gitを使ってフォルダをリポジトリに追加
git hubにgitのコマンドを使って自分の成果物を載せる方法をいまいちよく分かってなかったので今回ここで整理する
gitに関する知識はあまりないので間違えていたり足りない場合は教えていただきたい

少し前にワードクラウドで遊んだことがあったのでそのファイルをgit hubのリポジトリに追加する

ターミナルを開き、git hubに持っていきたいディレクトリに移動し以下のコマンドを実行

```
git init　#ディレクトリ以下がgitの管理下に置かれる

git remote add リポジトリ名 URL # git hubで作成したリポジトリのcodeから入手できるURL（HTTP）
　　　　　　　　　　　　　　　　　　　　　　　　
git add .　#全て追加 

git commit -m 'メッセージ'

git branch # ブランチ名を確認（デフォルトならmain）

git push リポジトリ名 ブランチ名 -f #　リモートの更新
```

リポジトリ名は最初はoriginと書くノリがある

しかしドラッグしてしまえばもっと早く追加できてしまうのでやりやすい方を選べば良いと思う
PHPでGCPのWorkload Identity連携をしようとしたら「Uncaught Google\Cloud\Core\Exception\ServiceException: invalid value in the type field」というエラーがでた

PHPライブラリ [google/cloud-bigquery](https://github.com/googleapis/google-cloud-php-bigquery) でBigQueryに接続しようとして以下のエラーに遭遇し、数時間程、時間が溶けたので備忘録として残しておきます。

## エラーメッセージ

```
PHP Fatal error:  Uncaught Google\Cloud\Core\Exception\ServiceException: 
invalid value in the type field in /var/www/app/vendor/google/cloud-core/src/RequestWrapper.php:397
```

## 原因

* `GOOGLE_APPLICATION_CREDENTIALS` で指定したJSONファイルのtypeが `external_account` だとエラーがでる
* 2023/06/28現在、PHPライブラリ [google-auth-library-php](https://github.com/googleapis/google-auth-library-php) がまだWorkload Identity連携に対応していなかった
  * GitHub Issue: https://github.com/googleapis/google-auth-library-php/issues/381
* `google/cloud-bigquery` は内部で `google-auth-library-php` を使用しているので、その影響でWorkload Identity連携が使用できなかった
  * `google-auth-library-php` を使用しているライブラリ全般で同様のことが起きていると思われる
  * 現在Workload Identity連携の部分の開発が行われているようなので、そのうち実装されそう？

## 対策

* `google-auth-library-php` がWorkload Identity連携に対応するまで待つ
* Workload Identity連携の代わりにGCPのサービスアカウントを使う
* 別のプログラミング言語＆ライブラリを使用する（Pythonは大丈夫だった）
* 自前でWorkload Identity連携に対応するコードを実装する

## コメント

* Pythonの `google-cloud-bigquery` では問題無くWorkload Identity連携ができていたので、PHPでできなくて少しはまった
* ソースコードがオープンで実装が確認できるというのはこんな時にありがたい
料金アラームをCloudWatchで設定して高額請求を回避しよう？

- 月の終わりにAWSマネージメントコンソールで請求ダッシュボードを開いたら下記の金額が表示されて気絶しました。
- Terraformの勉強で作ったEC2とRDSを起動させたままにして、停止するのを忘れていたことが原因です。
- 気絶から目覚めたら朝でしたが、2度とこのような思いをしないように急いで対処していきたいと思います。
![スクリーンショット 2023-06-28 22.08.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/13cab259-8351-e28d-4a8b-422e9f2f8b78.png)


## 目次
- 対処手順
- おわりに


## 対処手順
1. マネージメントコンソールを開く。
1. リージョンをus-east-1（バージニア北部）にする。
ここができれば90%完了しているようなもの。なぜなら東京リージョンでは、項目３を実行できないからです。何故かは知りません。
 ![スクリーンショット 2023-06-28 18.19.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/d7408c67-7760-371d-af94-d56cb5af7aa3.png)

1. 検索窓でCloudWatchを検索し、アラーム欄から請求を選択。右側にあるアラームの作成を押下。
![スクリーンショット 2023-06-28 21.48.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/45b15bc1-c49f-1220-58cb-f332a8655580.png)


1. 好きに条件を設定しましょう。とりあえず、閾値を設定すれば良いです。下記では料金が10USD以上になったときアラームを出すように設定しています。
![スクリーンショット 2023-06-28 18.19.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/70abfe80-5784-4539-6c55-4e6620dfa302.png)

1. あとは、ステップ通りに設定していきましょう。どの連絡先にアラートを通知するかなどを設定します。
![スクリーンショット 2023-06-28 18.21.02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/639329c9-05e1-6180-636e-a0c0b43400db.png)
![スクリーンショット 2023-06-28 18.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/c8eaa02b-0186-873d-b301-a9d6f1039223.png)
![スクリーンショット 2023-06-28 18.22.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/c0432010-2451-240a-955d-781fa6b463d5.png)

1. ここまでで99%完了です。データが不足と記載ありますが、そのうちAWS上のデータを読み取って正常に動きはじめます。
![スクリーンショット 2023-06-28 18.22.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/5e9c8c20-f18c-2e05-daf8-333d8f9f2468.png)

1. しばらく経つとアラートの設定が完了してました。私は今月分の請求がすでに10USDを超過しているのでアラームは異常とでています。
![スクリーンショット 2023-06-28 21.35.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/ed9114bc-13e4-250f-9d49-cba83ad4f371.png)

これでCloudWatchを使って使用料金を監視できるようになりました。もしCloudWatchのUI変わってたらごめんなさい。

<補足>
この記事を読んでいる方は東京リージョン使っている方がほとんどだと思いますが、CloudWatchのアラームの部分には、us-east-1で表示されていたものとは異なり”請求”の項目がなく、アラームの作成を押下してもメトリクスとかの設定をさせられます。（バージニア北部で設定しても東京リージョンで使用しているリソースの請求額ちゃんとみえます）
![スクリーンショット 2023-06-28 21.59.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/d3f0d880-a7fa-8aff-550f-778820099046.png)
![スクリーンショット 2023-06-28 21.59.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/0d584a97-3ae1-c6b3-fcb4-889765dd430e.png)



## おわりに
バージニア北部最高！
DAY2~3

<h1>>DAY2~3

20230627~28の記録

<h2>DAY2

おおよそ３か月でホームページとある程度の数の作品群をを作り上げて公開したいので、計画を立てました。
１から全部考えると時間がかかるので、chatgpt(3.5)に下書きをしてもらいました。
下書きをもとに、自分の予定ややりたいことを追加して週ごとに分配し、余裕をもたせた計画にしたつもりです。実際はどうなのかわからないけど…


バイトや家事、通院・入院のことを考えて、１週間あたり１９時間ほど作業ができると仮定しています
適宜調整はしていくつもりです
時間が多いか少ないかは素人なので判断がつかないです；；
まだわからないことがわからない状態といった感じです
アドバイスがあればどしどしお願いします＞＜

<details><summary>３か月の計画（クリックで表示）</summary>

```rb
'第１週
HTMLとCSSの学習・実践

第２週
HTMLとCSSの学習・実践
自分のホームページをどうしたいか考えて書き出してみる
可能ならひな形の下地みたいなのつくってみること
作品群の管理方法を考える（画像に名前をつけるときアルファベット数字ハイフンを使用して管理しやすくしたい）

第３週（１週間ほど入院するのでこの週はPC、タブレットを使えないと想定）
サイトの基本情報の作成
サイト名、ロゴ、キャラ作成
仮の利用規約を決める

第４週
サイズ確認や表示確認のためレイアウト用のテスト作品作成（ヘッダー画像など）
ホームページのひな形を作る
各作品を展示するページの作成

第５週
ダウンロード機能の実装
広告表示設定（googleadの登録と申請）
作品一覧のページを作成

第６週
作品のサイズ、サムネイルのサイズや仕様などをテンプレートにする
作品を作る（１週間に１０点）
トップページのブラッシュアップ
ホームページ全体の調整、動作確認、不具合修正

第７週
利用規約のページのブラッシュアップ
作品のダウンロードの仕方や使い方についてのページ作成
作品を作る（１週間に１０点）
ホームページ全体の調整、動作確認、不具合修正

第８週
作品を作る（１週間に１０点）
よくある質問のページ作成
ホームページ全体の調整、動作確認、不具合修正

第９週
作品を作る（１週間に１０点）
リクエストフォーム作成
ホームページ全体の調整、動作確認、不具合修正

第１０週
作品を作る（１週間に１０点）
お問い合わせフォームの作成
ホームページ全体の調整、動作確認、不具合修正

第１１週
作品を作る（１週間に１０点）
ホームページ全体の調整、動作確認、不具合修正

第１２週
作品を作る（１週間に１０点）
ホームページ全体の調整、動作確認、不具合修正'

```
</details>

長いから縮めたのですが、使い方あってるのかわからない:sweat_smile:

<h2>DAY3

html、cssの実践用の本を読んでます（コーディングはしてないです。流して読んでからコーディングする予定）
adobe XDでデザインカンプという便利なもの作れることを知りました。
便利そうなので自分のサイトを作るとときに使ってみたい！

モバイル版とPC版の作り方とコードを眺めました。
step1~3を読めたので今日のノルマはOK。
コツコツ頑張ります:star2:
element plus 2.3.7　<el-submenu>が動かない対策

``` diff_javascript
- <el-submenu index="3">
+ <el-sub-menu>
```

これで解決!
めちゅくちゃハマった
1年くらい前の参考書なのにもう記述方法が変わったみたいだな
さっき気づいたけど公式のelement-plusのドキュメントを見ると<el-sub-menu>と書いてあったので、参考書ばかり見ずに最新のドキュメントを読もう

ちな環境は
node: v18.16.1
element-plus: 2.3.7

某有名な参考書で勉強している人でハマっていたらかなり参考になると思う。
Proxmox7 を試してみる　その９　Nested kvm(migration)

# Nested kvm の移行
Nested kvm にした vm を migration してみます。自宅サーバ（外向け）は、紆余曲折？あり今、vmware workstation(Nested kvm)で立てているのをいい機会なので単独VMに昇格してみます。

# とりあえず qm で インポート、そしてネットワーク構成おかしくね？
qm コマンドで Proxmox にインポートします。ハードディスクを追加するなりするだけで VM として起動することを確認できますが、ホストOS の Nested kvm で設定した ネットワーク br0 が悪さをしていました。

ここら詳しいことは大先生にまかせることにしても、ネットワークディバイスの基本は「物理(1)：論理(n)」という構成になるハズでホストOSの br は・・・とかとかなる予定がですね、下記のようにちょいつ変でしたｗｗ。

・[nmcliコマンドの基礎](https://endy-tech.hatenablog.jp/entry/2018/09/08/140950)


```
# nmcli connection show
NAME        UUID                                  TYPE      DEVICE 
???? 1  bed50390-87ce-3787-ba6c-c5d31830c284  ethernet  ens18  
enp1s0       0cde4f9e-b91d-4e2e-9841-0495ecb51130  ethernet  --     
```

## 物理(1)：論理(1) で定義する
ほんとは、"NAME:DEVICE" が対になっていることを期待していたのですが、"????1" つー状態に。
でもってこのままだと 矛盾した状態なので物理(1)：論理(1)に再定義してみます。

コマンド実行後に `ens18` が 物理(1)：論理(1)に再定義 されたことを確認できます。

```
# nmcli connection modify bed50390-87ce-3787-ba6c-c5d31830c284  connection.id ens18  

# nmcli connection show
NAME   UUID                                  TYPE      DEVICE 
ens18  bed50390-87ce-3787-ba6c-c5d31830c284  ethernet  ens18  
enp1s0  0cde4f9e-b91d-4e2e-9841-0495ecb51130  ethernet  --   
```

## 無駄な情報を消しましょう
enp1s0 いらないというか `ifcfg-enp1s0` を！削除します。そして再起動しましょう。

```
# ls /etc/sysconfig/network-scripts
-rw-r--r--. 1 root root  357 Mar 24  2020 ifcfg-enp1s0
-rw-r--r--  1 root root  299 Jun 28 20:39 ifcfg-ens18

# rm /etc/sysconfig/network-scripts/ifcfg-enp1s0
```

## どうなっているのか？
よっしゃー、これで期待とおり！

```
# nmcli connection show
NAME   UUID                                  TYPE      DEVICE 
ens18  bed50390-87ce-3787-ba6c-c5d31830c284  ethernet  ens18  
```

## 固定IPを設定
そして 固定IPを設定してあげる

```
nmcli connection modify ens18 ipv4.address 192.168.0.9999/24
nmcli connection modify ens18 ipv4.gateway 192.168.0.1
nmcli connection modify ens18 ipv4.dns 192.168.0.1
nmcli connection modify ens18 ipv4.method manual
```

再起動後（どうだろう）

```
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: ens18: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 62:c6:ce:56:1a:9a brd ff:ff:ff:ff:ff:ff
    altname enp0s18
    inet 192.168.0.9999/24 brd 192.168.0.255 scope global noprefixroute ens18
       valid_lft forever preferred_lft forever
```

きたああああああああああああああああ

# 参考にさせて頂いたサイト様

・[【NetworkManager】IPアドレス設定で利用するnmcliコマンド一覧](https://isleofhoso.com/linux-nmcli-ipsetting/)
・[]()
・[]()
Python演習問題_カードゲーム編　はじめに②　【 カードゲーム　カードを配布する（問題）編 】

# カードゲームを作ろう
## クラスの定義　②

カードゲームを作るとき、マークと数字をきちんと定義してあげなくてはなりません。
マーク：Spade, Heart, Diamond, Club
数　字：A , 2 , 3 , 4 , 5 , 6, 7, 8 , 9 , 10 , J , Q , K　をつかって定義して
”はじめに”の問題で作った、Cardクラスを使って、CardGameクラスを作成しましょう。

```
[　条件　] 
Cardクラスは前回の回答で定義したものと同じ。

CardGameクラスでは、players（プレイヤー数）とcards_per_player（1人あたりのカード数）を引数として受け取り、ゲームの初期化とカードの配布を行います。_create_deckメソッドでカードデッキを作成し、_deal_cardsメソッドでカードをランダムに配布します。
最後に、display_handsメソッドを使用して各プレイヤーの手札を表示してください。
```
Python演習問題_カードゲーム編　はじめに②　【 カードゲーム　カードを配布する（解答）編 】

# カードゲームを作ろう
## クラスの定義　②

カードゲームを作るとき、マークと数字をきちんと定義してあげなくてはなりません。
マーク：Spade, Heart, Diamond, Club
数　字：A , 2 , 3 , 4 , 5 , 6, 7, 8 , 9 , 10 , J , Q , K　をつかって定義して
”はじめに”の問題で作った、Cardクラスを使って、CardGameクラスを作成しましょう。

```
[　条件　] 
Cardクラスは前回の回答で定義したものと同じ。

CardGameクラスでは、players（プレイヤー数）とcards_per_player（1人あたりのカード数）を引数として受け取り、ゲームの初期化とカードの配布を行います。_create_deckメソッドでカードデッキを作成し、_deal_cardsメソッドでカードをランダムに配布します。
最後に、display_handsメソッドを使用して各プレイヤーの手札を表示してください。
```


解答例は以下の通りです。

```Python
import random

class Card:
    suits = ["Spades", "Hearts", "Diamonds", "Clubs"]
    ranks = {
        "Ace": 1, "2": 2, "3": 3, "4": 4, "5": 5,
        "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
        "Jack": 10, "Queen": 10, "King": 10
    }

    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank
        self.value = self._get_value()

    def __str__(self):
        return f"{self.rank} of {self.suit}"

    def _get_value(self):
        return self.ranks[self.rank]


class CardGame:
    def __init__(self, players, cards_per_player):
        self.players = players
        self.cards_per_player = cards_per_player
        self.deck = self._create_deck()
        self.hands = self._deal_cards()

    def _create_deck(self):
        deck = []
        for suit in Card.suits:
            for rank in Card.ranks:
                card = Card(suit, rank)
                deck.append(card)
        return deck

    def _deal_cards(self):
        random.shuffle(self.deck)
        hands = []
        for _ in range(self.players):
            hand = []
            for _ in range(self.cards_per_player):
                hand.append(self.deck.pop())
            hands.append(hand)
        return hands

    def display_hands(self):
        for i, hand in enumerate(self.hands):
            print(f"Player {i+1} Hand:")
            for card in hand:
                print(card)
            print()


# ゲームの設定
players = 4  # プレイヤー数
cards_per_player = 5  # 1人あたりのカード数

# ゲームの開始
game = CardGame(players, cards_per_player)
game.display_hands()

```
Python演習問題_カードゲーム編　はじめに　【 カードゲーム　カードを定義して値をもたせる（問題）編 】

# カードゲームを作ろう
## クラスの定義

カードゲームを作るとき、マークと数字をきちんと定義してあげなくてはなりません。
マーク：Spade, Heart, Diamond, Club
数　字：A , 2 , 3 , 4 , 5 , 6, 7, 8 , 9 , 10 , J , Q , K　をつかって定義して
以下条件に従って、カードに値を付け加えましょう。クラスの名前はCardとしてください。

```
[　条件　] 
　クラスでは、ranksという辞書を追加し、値を設定してください。
（ランクのキーと値のペアは、トランプのゲームルールに従って設定が必要です）ここでは、
ブラックジャックに利用するように、10以上の札は、10と設定してください(Aは1で設定しましょう)。
さらに、_get_valueメソッドを追加し、カードの値を取得するためにself.ranks辞書を使用してください。
```
文字の表示がおかしくなった。

私がWebサイトを制作中に起こった文字がおかしくなる現象が起こりました。



ディレクターに指摘されるまで全然気付かなかったのですが、「文字のstyleがバラバラになっている」と、指摘を受け確認してみると、確かに一部文字の色が他より濃かったり、太かったりとばらつきがありました。



私はすぐに調べてみると、これじゃないかという記事を見つけました。



https://www.nishishi.com/css/webfont-anti-shaggy.html



ここに書いて入り通り、0.03deg文字をcssで傾けたところ、確かに直りました。



その場は、どれだけの数、表示バグがあるか調べてから、対策を考えるとなり、終わりました。


その後少しすると、「高」の文字がおかしい


という連絡が来て、



「どういうこと？」



と思い、調べてみると、どうやらそのおかしい文字は環境依存文字になっていました。


コード内には環境依存文字がちらほらあり、その全てが表示がおかしくなっている文字でした。



環境依存文字になっている箇所を修正することでこの問題は解決しました。


使ったプラグイン↓
https://marketplace.visualstudio.com/items?itemName=wayou.vscode-todo-highlight





上記のプラグインを入れておくと、事前にこういう不具合をなくすことが出来るので、Web制作をしている人は入れておく事をお勧めします。
Python演習問題_カードゲーム編　はじめに　【 カードゲーム　カードを定義して値をもたせる（解答）編 】

# カードゲームを作ろう
## クラスの定義

カードゲームを作るとき、マークと数字をきちんと定義してあげなくてはなりません。
マーク：Spade, Heart, Diamond, Club
数　字：A , 2 , 3 , 4 , 5 , 6, 7, 8 , 9 , 10 , J , Q , K　をつかって定義して
以下条件に従って、カードに値を付け加えましょう。クラスの名前はCardとしてください。

```
[　条件　] 
　クラスでは、ranksという辞書を追加し、値を設定してください。
（ランクのキーと値のペアは、トランプのゲームルールに従って設定が必要です）ここでは、
ブラックジャックに利用するように、10以上の札は、10と設定してください(Aは1で設定しましょう)。
さらに、_get_valueメソッドを追加し、カードの値を取得するためにself.ranks辞書を使用してください。
```


解答は以下のようになります。

```
class Card:
    suits = ["Spade", "Heart", "Diamond", "Club"]
    ranks = {
        "A": 1, "2": 2, "3": 3, "4": 4, "5": 5,
        "6": 6, "7": 7, "8": 8, "9": 9, "10": 10,
        "J": 10, "Q": 10, "K": 10　}

    def __init__(self, suit, rank):
        self.suit = suit
        self.rank = rank
        self.value = self._get_value()

    def __str__(self):
        return f"{self.rank} of {self.suit}"

    def _get_value(self):
        return self.ranks[self.rank]
```
デジタル庁のイラストレーション・アイコン素材を全部見る

**デジタル庁のサイトでアイコンやイラストが公開されました。** 👏👏👏

https://www.digital.go.jp/policies/servicedesign/designsystem/Illustration_Icons/

**攻めてます！！**

各種ニュースサイトでも紹介されています。

https://www.itmedia.co.jp/news/articles/2306/27/news179.html

https://forest.watch.impress.co.jp/docs/news/1512111.html

配布方法は以下の2通りです。

* Figmaで使う
* ダウンロードして使う

とりあえずどんな画像なんだろう？と興味を持った皆様のために、**全画像のキャプチャを取得しました！！**

## アイコン

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/527b8f97-63ef-e846-0c1f-e6a6f4dd20ef.png)

## イラスト

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41574/5c17047e-3995-f48d-c335-0270b9eefd7a.png)


個々の画像はこちらから確認できます。

https://moritalous.pages.dev/designsystem-assets
【Swift】1つの引数で複数の値を受け取る

# はじめに
引数の指定方法で知らない方法があったので記録しておきます。

# 実装
```swift
import SwiftUI

struct ContentView: View {
    var body: some View {
        List {
            makeListViewItem(items: "item1", "item2", "item3", "item4", "item5")
        }
    }
    
    private func makeListViewItem(items: String...) -> some View {
        ForEach(items, id: \.self) { item in
            Text(item)
        }
    }
}
```

# 解説
`型名...`で指定することによってカンマ区切りで値を渡すことができます。

**定義**
```swift
func xxxx(zzz: String...)
```

**使用**
```swift
xxxx(zzz: "item1", "item2", "item3", "item4", "item5")
```

# おわり
Swiftにはまだまだ知らない仕様がありそうです。
勉強不足を実感しました...
JavaScriptとSQLの日付解釈の違いについて

# はじめに
今回は、JavaScriptとSQLの日付解釈の違いについて、
ありがちな例を用いて解説してみようと思います。

例えば以下のような2パターンのコードがあるとします。
※Node.jsのTypeORMを使用しています。

## Aのコード 
```TypeScript
const hogeDate = "2023-07-30"
const date = new Date(hogeDate);

builder.andWhere('projects.hogeDate <= :hogeDate', { hogeDate: date });
```

## Bのコード
```TypeScript
builder.andWhere("projects.hogeDate <= DATE '2023-07-30'");
```

これらのコードは一見同じ結果になるように見えます。

# 何が問題なのか

まずAのコードですが、`hogeDate`はJavaScriptの`Dateオブジェクト`として作成されています。
JavaScriptのDateオブジェクトは、デフォルトでは実行環境のタイムゾーンに基づいて解釈されるため、dateの値は文字列`hogeDate（"2023-07-30"）`が自身のタイムゾーンに基づいて解釈された日付と時間になります。

それに対してBのコードでは、`DATE`を使って`SQLの日付リテラル`を直接使用しています。
このためSQLサーバの設定により、タイムゾーンが異なる可能性があります。
SQLでは日付リテラルは通常であれば、UTCで解釈されるので、
`"2023-07-30"`はUTCでの`"2023-07-30 00:00:00"`を指すことになるということです。

# まとめ

日付解釈問題は比較的あるあるかと思いますが、
使用しているデータベースとその日付や時間の解釈方法、および実行環境のタイムゾーン設定を考慮に入れて、日付/時間の比較を行うことが大事ということですね。

おしまい。
SA内に畳み込みやノルムや活性化関数を導入【LeViT】





**原論文**
LeViT: a Vision Transformer in ConvNet's Clothing for Faster Inference
https://arxiv.org/abs/2104.01136



# 関連研究

Vison Transformerの解説
https://qiita.com/wakanomi/items/55bba80338615c7cce73

CNN+ViTモデルの傾向【サーベイ】
https://qiita.com/wakayama_90b/items/96bf5d32b09cb0041c39



# 結論
SA内に畳み込みやノルムや活性化関数を導入．ダウンサンプリング方法が個性的．DeiTを上回る性能

# 概要
ViTをResNetのような階層型を採用する．階層型ViTモデルは数多く採用されている．多くの場合，ダウンサンプリングには線形射影や畳み込み，近傍4画素を連結されるような処理が採用されている．LeViTはSAのクエリ（Q）をダウンサンプリングすることでSAの出力をダウンサンプリングさせる処理を採用する．

# モデル構造
モデル構造は以下に示す．３ステージの階層型でSAとMLPを交互に処理する構造である．




![スクリーンショット 2023-06-28 21.10.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/267dd8a2-2ee4-7376-3cdd-b60d748d6869.png)

![スクリーンショット 2023-06-28 21.10.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/2ed65983-5d0b-8f7b-7a33-d63c05e6a96d.png)


## CNN構造を組み込んだSA
通常のSAを左，ダウンサンプリングするSAを右に示す．ここの入力は3次元の特徴量を入力とする．（通常のViTは2次元）SAの計算を実現するために，1x1畳み込みをQ,K,Vでそれぞれ行う．畳み込み後はBatchNormを通す．最後に1x1で特徴量を3次元に戻す．下図のHard wishは活性化関数の一種である．CNNはノルムや活性化関数を乱用するが，ViTはSAの後，MLPの後のLayerNormのみである．ViT内のSAにノルムや活性化関数を採用することで性能向上を期待する．


また，ダウンサンプリングするSAを右に示す．左と異なるのは，クエリの特徴量をダウンサンプリングするかである．SAの出力サイズはクエリに依存するため，クエリのサイズを小さくすることで出力サイズを小さくする．

![スクリーンショット 2023-06-28 21.10.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/a81bc922-f78d-0898-9d72-2ed2a4fcad54.png)




# 実験
ImageNetでDeiTを上回る精度を達成した．




# まとめ
今回は，ViTのSAにCNN構造を組み込むLeViTについて解説した．SA内に畳み込みやノルムや活性化関数を導入することで精度向上を達成した．
２重クリック防止（簡易？）

ふと２重クリックが気になって、Saveボタンを連打したら、いとも簡単に２重、３重の登録が行われました。

２重クリックで検索するとJavaScriptを用いた解説等がありましたが、極力コードを書かないローコードでやってみたので紹介します。

（Varidationでエラーがあった時等は、もう一度クリックできるようにしなければなりませんが、ちゃんと制御しないとそれがまた２重クリック発生の要因になります。）

Screenを右クリックし、Add Local Variableを選択。
名前をIsClick、Data TypeはBooleanにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/0fe89aab-f60f-0e6e-1aa6-75c7cbb27187.png)

SaveDetailのClient Actionを開き、Startのすぐ下にAssignを配置、クリックしたらIsClickがTrueになるようにします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/4cbb25ee-a689-69cb-cc07-af0bc5761253.png)

Startと配置したAssignの間に、Ifを配置し、ConditionにIsClickを入れ、TrueでEndに向かうようにします。
これで２重クリックが防止できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/a4caa91e-7005-1996-0118-582310a18195.png)

Form!.Valid?のFalseの線の上に、Assignを配置し、IsClickがFalseになるようにします。
これでValidationエラーがあった時は、もう一度Saveボタンが押せるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/254659/f7fe2718-b507-caad-3552-e9bba987289e.png)

なお、これはSaveボタンが成功した時はIsClickをFalseに戻したりはしませんので、別の画面に遷移してしまうことが前提です。

高速クリックでテストしてみましたが、今のところ重複登録はされません。
（高橋名人がやったら分かりませんが）
薬局の市場調査、分析、将来展望、洞察力成長、機会展望 2023-2033

リサーチネスターは、「薬局市場」と題する報告書を発行しました： このレポートは、世界の薬局市場を製品別、薬局タイプ別、用途別、地域別に市場細分化し、その詳細な概要を掲載しています。

さらに、詳細な分析については、市場の成長に関連する現在および将来の市場動向に関する詳細な議論とともに、業界の成長指標、阻害要因、需給リスクなどを網羅しています。

世界の薬局市場は、予測期間、すなわち2023年～2033年にかけて、年平均成長率～8%で成長する見込みです。市場は、製品別に処方箋とOTCに区分されます。このうち、処方箋市場は、世界的な慢性疾患の増加や高齢者人口の増加により、予測期間中最大の市場規模を維持すると予想されています。

このレポートについて業界の専門家に問い合わせる@ https://www.researchnester.jp/reports/pharmacy-market/4435 

世界の薬局市場は、自己免疫疾患の有病率の増加、老年人口の増加、高齢化に伴う様々な健康問題の発生により、大きく成長すると予測されます。また、承認された処方薬の増加や世界的な医療費の高騰も、予測期間中の市場成長を促進する主な要因のひとつです。 

![Pharmacy-Market.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3491677/4e6a4bec-cf37-e062-83fb-d722f020f807.jpeg)


地域的には、世界の薬局市場は、北米、欧州、アジア太平洋、中南米、中東・アフリカの5つの主要地域に分類されます。北米地域は、様々な慢性疾患の増加、大規模な薬局チェーンの存在、老人人口の増加、市販の処方薬使用の顕著な増加傾向などから、予測期間中に大きな成長を遂げると推定されます。 

本調査は、北米（米国、カナダ）、欧州（英国、ドイツ、フランス、イタリア、スペイン、日本）の市場を詳細に分析したもので、グローバルに展開しています、 ドイツ、フランス、イタリア、スペイン、ハンガリー、ベルギー、オランダ、ルクセンブルグ、北欧（フィンランド、スウェーデン、ノルウェー、デンマーク）、ポーランド、トルコ、ロシア、その他ヨーロッパ）、中南米（ブラジル、メキシコ、アルゼンチン、その他中南米）、アジア太平洋（中国、インド、ブラジル、メキシコ、アルゼンチン、その他中南米）、欧州（イギリス、フランス、ドイツ、オランダ、デンマーク、北欧（デンマーク）、トルコ、ロシア（デンマーク）、その他欧州（デンマーク））の市場について詳細な分析を行っています、 日本、韓国、インドネシア、シンガポール、マレーシア、オーストラリア、ニュージーランド、アジア太平洋地域のその他）、中東・アフリカ（イスラエル、GCC［サウジアラビア、UAE、バーレーン、クウェート、カタール、オマーン］、北アフリカ、南アフリカ、中東・アフリカ地域のその他）。また、市場規模、前年比成長率＆機会分析、市場プレイヤーの競争力調査、投資機会、将来展望の需要などからなる分析。

慢性疾患の世界的な有病率は、2020年までに59％増加すると言われています。

慢性疾患は、高齢になるにつれて、より一般的になります。慢性疾患には、心臓病、糖尿病、脳卒中、がん、関節炎などがあります。これらの疾患は、世界中で障害や死亡の主な原因となっています。このように、慢性疾患によって健康と生活の質は変化します。このような状態は、より多くのケア、タイムリーな治療、定期的な薬剤摂取を必要とします。したがって、慢性疾患の急増は、世界の薬局市場の成長を後押ししています。

関連市場レポートのサンプルコピーを請求する@ https://www.researchnester.jp/sample-request-4435 

しかし、訴訟提起のリスク、厳格な政府規制、医薬品やワクチンの使用に伴う合併症は、予測期間中、世界の薬局市場の成長に対する主要な抑制要因として作用すると予想されます。

本レポートでは、ユナイテッドヘルス・グループ、ウェルファーマシー、アルバートソンズ・カンパニーズ、ロイズファーマシー、シグナ、CVSヘルス・コーポレーション、ウォルマート、ウォルグリーン・ブーツ・アライアンス、クローガー、ライトエイドなどの企業プロファイルを含む世界の薬局市場の主要企業の競争シナリオも掲載しています。プロファイリングでは、事業概要、製品・サービス、主要な財務、最近のニュースや開発など、企業の重要な情報を掲載しています。全体として、本レポートは世界の薬局市場の詳細な概要を示しており、業界コンサルタント、機器メーカー、拡大機会を探している既存企業、可能性を探している新規企業、その他の関係者が、現在進行中および将来予想されるトレンドに従って市場中心の戦略を調整するのに役立つと考えられます。


リサーチ・ネスターについて

リサーチネスターは、戦略的な市場調査とコンサルティングのリーディングサービスプロバイダーです。私たちは、業界、コングロマリット、経営幹部が将来のマーケティング戦略、拡大、投資などについて賢明な決定を下すのに役立つ、公平で比類のない市場洞察と業界分析を提供することを目指しています。私たちは、すべてのビジネスが新しい地平線に拡大し、適切なタイミングで適切なガイダンスが戦略的な頭脳を通じて利用可能であると信じています。私たちの箱から出してすぐに使える考え方は、クライアントが将来の不確実性を避けるために賢明な決定を下すのに役立ちます。


【お問い合わせ先】 

ナオミ コスギ
Eメール: info@researchnester.jp 
米国の電話番号: +81 505 050 8480
【Git】複数のGitHub/GitLabアカウントで異なるSSH鍵を使用する方法

# はじめに
自社や受託で複数の案件を持つ場合、SSH鍵の作成方法をその度に調べるのは手間でした。
今回はそれぞれの手順をまとめておきます。

# SSH鍵の生成
まず、各アカウントに対応するSSH鍵を生成します。下記のコマンドで生成できます。

```bash
ssh-keygen -t rsa -b 4096 -C "your_email@example.com" -f ~/.ssh/id_rsa_accountname
```

# SSH設定の追加
次に、~/.ssh/configファイルに以下の設定を追加します。

```bash
Host github.com-accountname
    HostName github.com
    User git
    IdentityFile ~/.ssh/id_rsa_accountname
    IdentitiesOnly yes
```

ここで、"github.com-accountname"と"id_rsa_accountname"は先ほど生成したSSH鍵の名前に置き換えてください。

# GitHub/GitLabへ登録
生成した公開鍵（id_rsa_accountname.pub）を対象のサービスに登録します。

```bash
cat ~/.ssh/id_rsa_accountname.pub
```

### GitHubの場合

メニューから「Settings」->「SSH and GPG keys」へ移動し、鍵を登録します。

### GitLabの場合
メニューから「設定」->「SSHキー」へ移動し、鍵を登録します。

# リポジトリのクローン

最後に、リポジトリをクローンします。下記のように指定します。

```bash
git clone git@github.com-accountname:username/repository.git
```

ここで、"github.com-accountname"は設定したHost名、"username"はGitHubのユーザー名、"repository.git"はリポジトリ名に置き換えてください。

以上が、複数の案件を持つ際のSSH鍵の生成・登録の手順です。適切に設定すれば、それぞれの案件で異なるSSH鍵を使用することが可能となります。


# Tips
## SSHエージェントに登録
もし、上記手順を行ってもpushができない場合、ssh-agentに登録されていない可能性があります。
下記手順で確認してください。

```bash
echo $SSH_AUTH_SOCK
```

何か値が表示されればssh-agentは起動しています。
何も表示されない場合は、ssh-agentを起動してください。
例えば、一部のLinux環境（Ubuntuなど）ではssh-agentが自動的に起動しない場合があります。
その際は下記コマンドを実行します。

```bash
# ssh-agentが起動していない場合
eval `ssh-agent -s`
```

次に、ssh-addコマンドを使用して秘密鍵をSSHエージェントに追加します。


```bash
# MacOSの場合
ssh-add -K ~/.ssh/id_rsa_accountname

# 削除する場合
ssh-add -d ~/.ssh/id_rsa_accountname 
```

-Kオプションを付けることで、MacOSのキーチェーンにパスフレーズが保存されます。これにより、再起動後も再度パスフレーズを入力する必要がなくなります。

ここで、"id_rsa_accountname"は先ほど生成したSSH鍵の名前に置き換えてください。
Tarraformを使ってAWSにWebサーバを構築 #2 ~Terraformをインストールする~

## 目的
EC2にNginxがインストールされた状態を作り出し、ブラウザからデフォルトページが確認できることをゴールとする。
インフラ構築はTerraformでコード化することで再現性、再利用性、速度などが手作業に比べると高い。
[GitHubリンク](https://github.com/keitasato/terraform-nginx)


### 手順
1. [TerraformからAWSリソースを操作できるように設定する](https://qiita.com/kekkepy/items/4185a621e5d3cc75016b)
1. [Terraformをインストールする](https://qiita.com/kekkepy/items/1b3f4f14bbc2d2dc2c9b)
1. [TerraformでEC2サーバを立ち上げてみる](https://qiita.com/kekkepy/items/8b84fc0c39313267a078)
1. [ネットワークを整える(VPC, サブネット, ルーティングテーブル,インターネットゲートウェイ)](https://qiita.com/kekkepy/items/c941c00536af57bae163)
1. [セキュリティグループ(ファイアウォール)を設定する](https://qiita.com/kekkepy/items/47dcda4d9a7a2064382f)
1. [Webサーバ用EC2を立ち上げる](https://qiita.com/kekkepy/items/81bfa5d542c9160d430b)
1. [Webサーバが立ち上がる際にWebサーバソフトをインストールするように設定する](https://qiita.com/kekkepy/items/209f7ddb29fb5af65a6e)

#### 今回の到達点
Terraformをインストールする

##### Step1. tfenvのインストール
terraformを複数バージョンインストールすることも考えて、TerraformをPCに直接インストールするのではなく、tfenvをインストールした上にTerraformをインストールする。
GitBashで以下を実行
```bash:
$ cd ~
$ git clone https://github.com/tfutils/tfenv.git .tfenv
```

##### Step2. tfenvにパスを通す
~/.bashrc を作成しファイルの内容を以下のようにする
```txt:~/.bashrc
export PATH=$PATH:/c/Users/[ユーザ名]/.tfenv/bin
```

パスが通ったかを以下で確認
```bash:
$ tfenv
tfenv 3.0.0-18-g1ccfddb
Usage: tfenv <command> [<options>]

Commands:
   install       Install a specific version of Terraform
   use           Switch a version to use
   uninstall     Uninstall a specific version of Terraform
   list          List all installed versions
   list-remote   List all installable versions
   version-name  Print current version
   init          Update environment to use tfenv correctly.
   pin           Write the current active version to ./.terraform-version
```

##### Step3. terraformのインストール
インストール可能なバージョンを調べる
```bash:
$ tfenv list-remote
```

インストールしたいバージョンを選択して以下のコマンドでインストール
```bash:
$ tfenv install [version]
```

インストールしたバージョンのTerraformを使うように設定
```bash:
$ tfenv use [version]
```

Terraformが使えるようになったかの確認。バージョンが表示されれば無事インストールされている。
```bash:
$ terraform version
Terraform v0.14.6
```
ViTに局所的バイアスを持つCNNを追加【CeiT】




**原論文**
Incorporating Convolution Designs into Visual Transformers
https://arxiv.org/abs/2103.11816


**日本語解説**
Incorporating Convolution Designs into Visual Transformers
https://speakerdeck.com/abeta/incorporating-convolution-designs-into-visual-transformers

# 関連研究

Vison Transformerの解説
https://qiita.com/wakanomi/items/55bba80338615c7cce73

CNN+ViTモデルの傾向【サーベイ】
https://qiita.com/wakayama_90b/items/96bf5d32b09cb0041c39



# 結論
ViTに局所的バイアスを持つCNNを追加してImageNetで精度向上．



# 概要
画像認識分野のスタンダードになってきたViTがある．しかし，ViTには様々な問題点がある．その1つとして，局所バイアスが無いことで大量のデータが必要であり，ImageNetでは学習不十分である．
ViTは画像全体を並列に処理するため，画像全体を考慮する利点があるが，近い画素は関係が深いといった局所的バイアスの獲得が困難である．この前提知識を補うために大量のデータが必要である．反対に，CNNはカーネルの範囲（$3 \times 3$）の特徴量を認識する構造であり，局所的バイアスを獲得しImageNetではViTを上回る精度である．
ここで，ViTに局所的バイアスを追加するために，CNNをViTの構造に導入する．これが，CeiTである．




# モデル構造
CeiTのモデル構造を下図に示す．CNNは，パッチトークンとLeFFで導入される．ViTの構造と異なる部分を以下に解説する．

![スクリーンショット 2023-06-28 20.27.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/f45a7ddd-707e-5a0b-f95b-0e877d9af9f2.png)

<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/98eaed7e-49bf-2cdc-a4e2-276284ce6807.png">




## パッチトークン
ViTのパッチトークンは下図の上ルートで作成される．CeiTは下ルートを採用する．はじめに，1層の畳み込みとMax-poolingを行い，パッチ分割する．
これによって，画像のエッジなどの局所的な情報（Low-level）を獲得する．


![スクリーンショット 2023-06-28 20.38.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/0e58d151-eeb1-2329-7263-a9961afa58c1.png)


## LeFF
LeFFはFFNに畳み込みを導入して局所的な認識を補助する．

1. パッチトークンを線形射影
1. ３次元に並べる
1. $3 \times 3$or$5 \times 5$のDW畳み込み（空間情報のみを認識）+バッチノルム
1. 2次元に戻す
1. 線形変換

これにより，MSAの大局的な認識，LeFFの局所的な認識を交互に行い有効な認識を期待する．




![スクリーンショット 2023-06-28 20.39.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/ed19ad0c-d188-330e-3333-6d1273254b6a.png)


## LCA
LCAはクラス識別をするMSAを別に用意してCeiTのOutputとするモジュールである．LCAはMSAとFFNが一層ずつ用意される．入力には，各層のクラストークンが使用される．
ViTは各層で抽出される特徴は異なる．ViTの分析によって，浅い層では局所的な認識，深い層では大局的な認識をする傾向がある．これらの情報を各層で集約したクラストークンを使用する．


# 実験
ImageNetを含む，様々なデータセットで良い精度を達成した．
また，CeiTはDeiTと比較して3倍の速さで同じ精度を達成する．


<img width="400" alt="mojikyo45_640-2.gif" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457775/09a5edba-f4c1-d1ac-1828-dd47abafe81a.png">


# まとめ
今回は，ViTに局所的バイアスを持つCNNを追加するCeiTについて解説した．各層のクラストークンを使用してSAをすることは新しいですね．
RubyでAtCoder ABC238(A, B, C)を解いてみた

# はじめに
Webエンジニアを目指して、RubyやRailsをいじってます。
今回は、RubyでAtCoder ABC238のA, B, Cを解きました。備忘録として解き方をまとめていきたいと思います。

# A - Exponential or Quadratic
https://atcoder.jp/contests/abc238/tasks/abc238_a
```ruby:a-238.rb
n = gets.to_i
puts 2 ** n > n ** 2 ? "Yes" : "No"
```

# B - Pizza
https://atcoder.jp/contests/abc238/tasks/abc238_b
```ruby:b-238.rb
gets
a = gets.split.map(&:to_i)

array = [360]
deg = 0
a.each do
  deg += _1
  array << deg % 360
end

array.sort!
ans = array.first
array.each_cons(2){ ans = [ans, _2 - _1].max}
puts ans
```
## 解説
最初に切れ込みが入る位置（0からの角度）を求め、array配列に格納した後昇順にソートします。そして、隣り合う要素の差（ピザの中心角）の最大値を更新していくことで答えを求めることができます。

# C - digitnum
https://atcoder.jp/contests/abc238/tasks/abc238_c
```ruby:c-238.rb
n = gets.to_i

mod = 998244353
ans = 0
n.to_s.size.times do
  m = [9 * (10 ** _1), n - (10 ** _1) + 1].min
  ans += (m * (m + 1)) / 2
end
puts ans % mod
```
## 解説
（[公式解説](https://kazun-kyopro.hatenablog.com/entry/ABC/238/C)を参考にしました）

公式解説にあるように`N-10^(i-1)+1`を求めればいいのですが、それぞれの桁数に応じて`f(N)=9*10^(i-1)`個あることがわかるので、これらのうち小さい方を使う必要があります。最後に、求めた総和を`998244353`で割った余りを求めることで解くことができます。

https://qiita.com/shoya15/items/50fd17e37d7c64f2b166
grep

```
#!/bin/sh -v
      ls lo* -1
lo1
log1
log?1
logS0
logS1
logS2
logg1
loggg1
      find . -maxdepth 1 -name lo\*  | grep -E 'log.[0-2]'
./log?1
./logS0
./logS1
./logS2
./logg1
      find . -maxdepth 1 -name lo\*  | grep -Ev 'log.[0-2]'
./lo1
./log1
./loggg1
      find . -maxdepth 1 -name lo\*  | grep -E 'log?[0-2]'
./lo1
./log1
      find . -maxdepth 1 -name lo\*  | grep -E 'log*[0-2]'
./lo1
./log1
./logg1
./loggg1
      find . -maxdepth 1 -name lo\*  | grep -E 'log+[0-2]'
./log1
./logg1
./loggg1
      find . -maxdepth 1 -name lo\*  | grep -E 'log?[0-2]'
./lo1
./log1
```
windowsでcurlコマンドでJSONを送信する

# はじめに
GolangでAPIの作成をしている際にハンドラがきちんと動作するか確認しながら開発をしている際に、curlでjson形式のデータをPOSTする際にうまくリクエストできず、エンコードできなかったので解決法を残しておきます。

# curlコマンドとは
>cURLとは、主にUNIX系OSでよく利用されるコマンドおよびプログラムの一つで、様々なプロトコル（通信手順）を用いてURLで示されるネットワーク上の場所との間でデータの送受信を行うもの。オープンソースソフトウェアとして公開されている。

API作成をしていると、HTTPリクエストをしながら作業をするシーンが多くあります。
そのときに選択肢として一つ使えるのがcurlコマンドというわけです。

詳しい使い方などはこちらを参照してください。
https://qiita.com/yasuhiroki/items/a569d3371a66e365316f


# curlでのJSON形式のPOSTのコマンド
```
$ curl https://xxxxx.net/xxxxxx　-X POST -H "Content-Type: application/json" -d '{"name":"太郎", "age":"30"}' 
```

上記のような形で紹介されているサイトがほとんどでした。

<table>
  <caption>curlオプション</caption>
  <thead>
    <tr>
      <th>オプション</th> <th>説明</th>
    </tr>
  </thead>
  <tr>
    <td> -X </td> <td>HTTPメソッドの指定</td>
  </tr>
  <tr>
    <td> -H </td> <td>HTTPリクエストでリクエストヘッダを指定</td>
  </tr>
  <tr>
    <td> -d </td> <td>POST でフォームを送信する</td>
  </tr>
</table>

しかし私の環境(windows10)ではうまくいかず。。。

# 問題
```go
func PostArticleHandler(w http.ResponseWriter, req *http.Request) {
	length, err := strconv.Atoi(req.Header.Get("Content-Length"))
	if err != nil {
		http.Error(w, "cannot get content length\n", http.StatusBadRequest)
		return
	}
	reqBodybuffer := make([]byte, length)

	if _, err := req.Body.Read(reqBodybuffer); !errors.Is(err, io.EOF) {
		http.Error(w, "fail to get request body\n", http.StatusBadRequest)
		return
	}
	defer req.Body.Close()

	var reqArticle models.Article
	if err := json.Unmarshal(reqBodybuffer, &reqArticle); err != nil {
		http.Error(w, "fail to decode json\n", http.StatusBadRequest)
		return
	}


	article := reqArticle
	jsonData, err := json.Marshal(article)
	if err != nil {
		http.Error(w, "fail to encode json\n", http.StatusInternalServerError)
		return
	}

	w.Write(jsonData)
}
```
上記コードにおいて、エンドポイントは/articleで,メソッドはPOSTのみ受け付けます。
そのため、ターミナル上で
```
curl http://localhost:8080/article -X POST -d '{"title" : "a","contents":"b","user_name":"c"}'
```
とコマンドを入力すると結果は以下のようになりました。
```
//結果
{"article_id":0,"title":"","contents":"","user_name":"","nice":0,"comments":null,"created_at":"0001-01-01T00:00:00Z"}
```

このようにうまくいかず。。。
POSTで送信しているはずの「title」「contents」「user_name」がデータとして入っていないことがわかります

# 解決策
上記コマンドを
```
curl http://localhost:8080/article -X POST -d "{\"title\":\"a\",\"contents\":\"b\",\"user_name\":\"c\"}"
```
このように変更すると

```
//結果
{"article_id":0,"title":"a","contents":"b","user_name":"c","nice":0,"comments":null,"created_at":"0001-01-01T00:00:00Z"}
```

さっきは入ってなかったデータが入ってます！！
このようにwindowsでは二重引用符「"」の前にエスケープ「\」をつけてエスケープする必要があるようです。

# 原因
そもそもJSONというのはkey-value型のデータ形式であり、
```
{

 "Key": "Value",

 "キー": "値",

 "Key1": "Value1"

}
```
このような記述になります。
また、コマンドプロンプトにおいて文字列を渡す場合は二重引用符「"」を付ける必要がある。
このことから、失敗していたコマンドでは"title"や"a"をただの文字列だと認識し、JSON形式のデータだと認識していなかったようです。
(コマンドプロンプトで{"title":"a"}と入力しても「title」と「a」という文字列と認識(?)されてしまう。)

つまりコマンドプロンプト側に二重引用符「"」も含めてデータなんだと認識させる必要があります。
ここで「\"」としてエスケープすることで二重引用符「"」を認識してくれるようになったのです。
(自分が調べた感じこのような解釈になりました。間違っていたり、知見がある方は教えてください！！)

# 最後に
エラー文が出てくれないのでなかなか解決しづらいエラー（？）でした。
コマンドではこのようにOSで差異が出てしまうと感じたため、クライアントツールを導入しました！
それでは、みなさん楽しいエンジニアライフを！
【Python】JSONファイルからランダムにエントリを選び、それぞれのエントリを連番で命名された個別のファイルに保存する方法

# 概要
- 指定したJSONファイルからランダムなエントリを抽出し、それぞれのエントリを個別のファイル`001_product.json`から`100_product.json`に保存する方法を紹介します。

# サンプルコード解説

```py
import json
import random
import os

# JSON ファイルからランダムにエントリを抽出する関数
def extract_random_entries(json_file, num_entries):
    with open(json_file, 'r', encoding='utf-8') as f:
        data = json.load(f)

    entries = random.sample(data, num_entries)
    return entries

# JSONファイルのパスを指定
json_file_path = './product.json'
# 抽出するエントリ数を指定
num_entries_to_extract = 100

random_entries = extract_random_entries(json_file_path, num_entries_to_extract)

# ファイルを作成するディレクトリを取得(dirnameは、パス文字列からファイル名を除いたディレクトリの部分を取得)
output_directory = os.path.dirname(json_file_path)

# 001_product.jsonから100_product.jsonまでのファイルを作成
for i, entry in enumerate(random_entries, start=1):
    output_file_path = os.path.join(output_directory, f'{str(i).zfill(3)}_product.json')
    with open(output_file_path, 'w', encoding='utf-8') as f:
        json.dump(entry, f, ensure_ascii=False, indent=4)

```

## ゼロパディングについて
- 今回、`1`ではなく、`001`というように、桁数に満たない部分をゼロで埋めています。必要ない場合は、`zfill`のところを変更して下さい。
- `f'{str(i).zfill(3)}_product.json'`については、以下の記法もあります。
 
```py
destination_file = f"{i:03}_product.json"
```

## `enumerate()`関数について
- リストやイテレータなどの要素にインデックスを付け加えるために使用される関数です。
- 上記サンプルコードの場合、`random_entries`リストの要素に対してループ処理を行いながら、それぞれの要素とそのインデックスを取得します。
- `start=1`という引数は、インデックスの開始値を指定しています。インデックスは通常`0`から始まりますが、`001`から連番で命名させるために指定しています。

## 日本語のエンコーディングエラーについて
- JSONファイルに日本語が含まれている場合、JSONファイルの読み込み時や書き込み時に`encoding='utf-8'`を指定しないとエンコーディングのエラーになりました。また、`json.dump`の`ensure_ascii=False`引数を指定することで、日本語などの非ASCII文字も正しく処理されるようになります。
【覚書】起動しているコンテナのログを1 lineで全て確認する

# 結論

```
$ docker ps -aq
c4d2a7431041
e129eaa57cd5

$ docker ps -aq | xargs -L 1 docker logs

```
# 使い所
CodeBuildでCIを回す機会があり、docker がUnhealthyになる状況があった。
その中で、`mvn verify`を用いてcontainerのup/downを行っていたため、`buildspec.yml`に`codebuild-breakpoint`と記載してSSMを用いてコンテナ起動後の状態で止めることはできない。
そのため、`mvn verify`でコンテナがコンテナがUnhealthyになった後にpost_buildフェーズで上記コマンドを実行することで、起動後のログを標準出力により取得した。

# 参考
https://docs.aws.amazon.com/ja_jp/codebuild/latest/userguide/session-manager.html
基本情報技術者試験

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3457284/d66d3a3a-023a-903f-e2ee-550625d4bfc9.png)
１：基本情報技術者試験とは経済産業大臣が行う国家試験の一種です。

２：午前の部
テクノロジ系
第1章 コンピュータ化学基礎理論
第2章コンピュータ構成要素とハードウェア
第3章 ソフトウェア
第4章 コンピュータシステムの構成
第5章 データベース(SQLについては別途記載予定)
第6章 ネットワーク
第7章 セキュリティ
第8章 システム開発技術
第9章 データ構造、アルゴリズム、プログラミング

マネジメント系
第1章 プロジェクトマネジメント
第2章 ITサービスマネジメント
第3章 システム監査

ストラテジ系
第1章 システム戦略
第2章 経営戦略

午後の部
テクノロジ系
第1章 浮動小数点表現、論理演算と論理回路
第2章 機械語命令の読解
第3章 コンパイラの原理
第5章 正規化とSELECT文の記述
第6章 IPアドレスの設定とサーバの設置
第7章 VPN
第8章 プロセスフロー図
第9章 擬似言語プログラム、基本的な処理、二次元配列を利用した処理
第10章 表計算の基礎、複雑な関数、マクロ

マネジメント系
第1章 アンドバリュー分析、ファンクションポイント法
第2章 サービスデスク

ストラテジ系
第2章 市場分析
GraphQL: Resource not accessible by integration (repository.pullRequest.statusCheckRollup.nodes.0)の解消方法

# 概要
プライベートレポジトリにおいて、Github app tokenを利用して [gh command](https://cli.github.com/manual/index)をGHAで実行しprのcheck_suiteの情報を取得する際に権限エラーが発生した。

# 実行したコマンド
```
gh pr view ${PR_NUMBER} --json statusCheckRollup
```
# エラー内容
```
GraphQL: Resource not accessible by integration (repository.pullRequest.statusCheckRollup.nodes.0)
```
もしくは
```
GraphQL: Resource not accessible by integration (repository.pullRequest.statusCheckRollup.nodes.0.commit.statusCheckRollup.contexts.nodes.0.checkSuite.workflowRun)
```

# 対処法

Github appに以下の権限を付与 (権限はすべてreadで充分)
- Repository permissions
  - Actions
      - 2つめのエラー
  - Checks
      - 1つめのエラー
  - Contents
      - 1つめのエラー
  - Metadata
  - Pull requests
サブディレクトリ上でGithubCLIのruby/setup-rubyを実行する方法

# 動機
GithubCLIでRailsを動かす場合`ruby/setup-ruby`を使うが、これはトップディレクトリがRailsのディレクトリじゃないとエラーを吐く。

ディレクトリ構成は以下のようになっています。
```
- top
    - backend
        - app
        - bin
        - config
        ...
    - frontend
```

# 解決策
`uses: ruby/setup-ruby@v1`をする前に`backend`ディレクトリの中身をトップディレクトリに持ってきます。
以下の処理を`uses: actions/checkout@v2`と`uses: ruby/setup-ruby@v1`の間に書いてください。
```
- name: Move to top directory
  env:
    SUB_DIR: backend
  run: |
    path=`pwd`
    mv $path/$SUB_DIR /tmp
    for dir in `find $path -maxdepth 0`
    do
      rm -rf $dir
    done
    for dir in `find /tmp/$SUB_DIR -maxdepth 0`
    do
      mv $dir $path
    done
```
`backend`ディレクトリを`/tmp`に一旦移してカレントディレクトリの中身を全て削除し、`/tmp`に移した中身をカレントディレクトリに戻します。

# おわり
かなり愚直なやり方になってしまったので、もっといい方法をご存知の方がおられたらコメントで指摘していただけると助かります。
内製開発組織作りについて

# はじめに
本田技研工業の田と申します。私はサーバエンジニアとしてキャリアをスタートし、その後アーキテクトやテックリードの役割、ソフトウェアの品質保証、セキュリティに関わる業務を経験しました。現在は内製開発チームのリーダーを務めています。
約2年前に我々の組織ではソフトウェア内製化の取り組みが始まりました。私はその立ち上げメンバーの一員であり、今回は振り返りとして、課題や取り組みについてお話ししたいと思います。
# TL;DR
- 内製開発の必要性
- 内製開発の課題
- 我々の取り組み
# 我々とは

現在、私たちが所属しているデジタルサービス開発課は、マトリックス組織構成を採用しています。内製開発チームは、モバイルアプリとサーバの開発に特化した職能型チームであり、デジタルプロダクトの内製開発と持続的な進化を担当しています。
![Untitled.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3083912/22f677b4-d6f8-866d-2d48-838072d4aaec.png)

## なぜ内製開発必要か

デジタルサービス領域では、外部および内部の環境が複雑かつ急速に変化しており、顧客に対して迅速かつ頻繁に価値を提供する必要があります。デザイン思考、アジャイル開発、DevOpsなど、さまざまなプロセスや開発手法が存在しますが、これらを効果的に実践するためには、専任していて、安定していて、自律的にやり方を改善し、継続的に学習しながら、ミッション達成を目指すチームが必要です。
このような高速な実験や学習を行うチームは、自ら作り上げるしかありません。

# 課題

ソフトウェア内製化において、私たちは以下の課題に直面しています。
#### プロダクト横断のナレッジ蓄積  
ソフトウェア開発の様々な領域やプロダクトで得られる知識や経験を、チーム全体に効果的に共有するこことが不可欠です。
#### スケールアウト、スキルアップ
ソフトウェア内製化の進行に伴い、私たちの開発チームの規模や活動範囲は拡大しています。この拡大に対応するためには、メンバーのスキルアップと組織のスケールアウトが必要です。新しいメンバーの採用や育成、トレーニングプログラムの整備が重要な課題となっています。

# 取り組み

内製開発チーム以下の取り組みを行なってます。

#### 自分史開示 
チームビルディングの一環として、毎週の定例会で15分間の自己開示を行っています。各メンバーは重要な経験やバックグラウンド、価値観を共有し、チームメンバー間の信頼構築とコミュニケーションの促進を図っています。

#### テックトーク
定期的にテックトークを実施し、業務上の知見や担当領域における有益な情報を共有しています。各メンバーが専門分野やプロジェクトで得た知見やノウハウを共有することで、チーム内での情報共有と学びの文化を築いています。

#### ワイガヤ

ワイガヤは、年齢や職位にとらわれずにメンバー同士が自由に議論し合う、Honda独自の文化です。定期的にワイガヤを開催し、メンバー同士が自由に意見交換を行っています。参加者は自身の考えや課題を共有し、チーム内のコミュニケーションを活発化させ、創造性やエネルギーの向上、そしてチームへの帰属意識の高まりを促しています。

#### 1on1 

個々のメンバーとは隔週で1on1と呼ばれる個別のコミュニケーション時間を設けています。1on1の場では、メンバーは以下の内容を報告し、上司はメンバーの状況を把握し、サポートやガイダンスを提供する機会となります。

【1on1内容】
　1. 幸福度（ハピネス指数）
　2. 過去2週間の進捗、成果、取り組み、課題などの振り返り
　3. キャリア開発や自己研鑽に関する相談など
1on1を開催することで、個人のパフォーマンスやチームの効率性を向上させることを目指しています。

#### ソフトウェア開発勉強会

ソフトウェア開発勉強会では、外部の有識者を招き、ソフトウェア開発に関するトピックについて学ぶ機会を提供しています。勉強会は隔週で行われ、1回あたりの所要時間は1.5時間です。各トピックは通常3ヶ月間の期間で開催されます。過去2年間では、JavaScript/TypeScriptおよびFlutterに焦点を当てた勉強会を実施しました。勉強会を通じて、参加者は基礎から応用まで幅広く学び、実践的なスキルを磨く機会を得ることができます。これにより、参加者はプロジェクトに自信を持って取り組むだけでなく、チーム全体の技術レベル向上にも貢献します。

#### ハッカソン

昨年、部門内で初めてハッカソンを開催しました。ハッカソンには、開発者だけでなく、企画やUI/UX担当など、さまざまな役割を持つメンバーが参加するようになります。参加者はチームを組み、与えられた課題やテーマに対して一定期間内でアイデアを出し合い、プロトタイプの開発に取り組みます。
ハッカソンはチームの一体感を醸成し、お互いを刺激し合う絶好の機会を提供するため、今後も定期的に実施する予定です。

# 最後

ソフトウェアの内製化は非常に重要な取り組みであり、その実現には困難な側面も多く存在します。しかし、私たちはこの挑戦を続けることで、多くの顧客満足サービスを提供したいと考えています。
Fast Inverse Square Rootの一般化を考えてみた

https://www.youtube.com/watch?v=p8u_k2LIZyo&ab_channel=Nemean

Fast Inverse Square Rootという、Quakeという昔のゲームで使われた超絶すごいアルゴリズムがありまして、計算コストが割りと高い$y = 1/\sqrt x$を超高速で計算できます。

上のビデオで詳しく解説されていますが、この手法は浮動小数点数の仕様をハックしきっていて最高なので、その一般化版を考えてみました。つまり、

$y = x^{-1/2}, x^{-1/4}, x^{-1/8}...$ に対する解です。

これ全部$1/2^n$の形なので$log_2$したときにbit shiftの形に落とし込めるのがミソです。

ビデオで紹介されている箇所はなるべく端折りますが、以下でやっていきます。

（符号少数点数の符号部は全て正とします。）

$\Gamma = y^{-1/2^n} $
$\Leftrightarrow log_2{\Gamma} = {-1/2^n} log_2{y}$
$\Leftrightarrow log_2{(1+\frac{M_{\Gamma}}{2^{23}})2^{E_{\Gamma}-127}} = {-1/2^n} log_2{(1+\frac{M_{y}}{2^{23}})2^{E_{y}-127}}$
$\Leftrightarrow 1/2^{23} (M_{\Gamma} + 2^{23} E_{\Gamma}) + \mu - 127 = 
   {-1/2^n} (1/2^{23} (M_{y} + 2^{23} E_{y}) + \mu - 127)$
$\Leftrightarrow M_{\Gamma} + 2^{23} E_{\Gamma} = (2^{23} + 2^{23-n})(127-\mu) -1/2^n (M_{y} + 2^{23} E_{y})$

右辺第一項は定数ですが、適当にn=5,そして動画でも出ていた$\mu=0.043$で計算した場合、
(2^23+2^18)(127-0.043) = 1098273521.66 ≒ 1098273522 = 0x417652F2
となります。
最後の数式右辺第二項の$-1/2^n$が、-してn回bit shiftに当たります。

次にNewton法のパートですが、

$y = \frac{1}{x^{1/2^n}}$

を変形して

$y^{-2^n} - x \equiv f(y)$

とします。

導関数は、

$f'(y) = -2^n y^{-2^n-1}$

です。

その為、値更新のための漸化式は、

$y_{n+1} = y_n - \frac{f(y)}{f'(y)}$
$= y_n - \frac{y_n^{-2^n} - x}{-2^n y_n^{-2^n-1}}$
$= y_n + (1 + 1/2^n) y_n - 1/2^n x y_n^{2^n + 1}$

です。

なので、全体のコードとしては以下です（n=5の場合）。

```c
float calcPower(float x, int power){
    tmp = x // puts x^(2^n) of x;
    ans = 1;
    while (power > 0){
        if (power % 2 == 1){
            ans *= tmp;
        }
        tmp *= tmp;
        power >>= 1;
    }
    return ans;
}

float Q_rsqrt( float number )
{
 const int n = 5;
 long i;
 float x2, y, y_pow;
 const float newton1 = 1.03125; // (1 + 1/2^n)
 const float newton2 = 0.03125; // (1/2^n)
 const float newton3 = 33;      // (2^n)

 x2 = number * 0.5F;
 y  = number;
 i  = * ( long * ) &y;                       // evil floating point bit level hacking
 i  = 0x417652F2 - ( i >> n );               // what the fuck?
 y  = * ( float * ) &i;
 y_pow = calcPower(y, newton3)
 y  = y * ( newton1 - newton2 * x * y_pow  );   // 1st iteration
 y_pow = calcPower(y, newton3) // 2nd iteration, this can be removed
 y  = y * ( newton1 - newton2 * x * y_pow  );   // 2nd iteration, this can be removed

 return y;
}
```

工夫として、累乗の部分は高速化を加えてみました。a^5を計算するとき、a*a*a*a*aだと乗算5回ですが、a^2を計算、a^2*a^2を計算、a^4*aを計算だと乗算3回で済むことを利用しています。

0x417652F2のマジックナンバーや、newwton1, 2, 3の変数は各自でnに合わせて計算していただければと思います。また、これ申し訳ないのですが手元にCの環境がないため検証できません。どなたか検証していただければ嬉しいです。
man, whatis

```sample.sh
#!/bin/sh -v
    whatis passwd
    man 1 passwd | head -n 10
    echo "------------------------------"
    man 5 passwd | head -n 10
```
```
passwd (1)           - ユーザパスワードを変更する      #usercommand
sslpasswd (1ssl)     - compute password hashes
passwd (5)           - password file                 #file 
                               :
                               :
PASSWD(1)                                                                                  General Commands Manual                                                                                  PASSWD(1)



名
       passwd - ユーザパスワードを変更する

書
       passwd [-k] [-l] [-u [-f]] [-d] [-n mindays] [-x maxdays] [-w warndays] [-i inactivedays] [-S] [--stdin] [username]

------------------------------
PASSWD(5)                                                                                 Linux Programmer's Manual                                                                                 PASSWD(5)



NAME
       passwd - password file

DESCRIPTION
       The  /etc/passwd  file  is  a text file that describes user login accounts for the system.  It should have read permission allowed for all users (many utilities, like ls(1) use it to map user IDs to
       usernames), but write access only for the superuser.
```
Deno deploy で Deno KV を使用できるようになったらしい

自分用の忘備録なので、殴り書きです。
Deno deploy で Deno KV を使用できるようになったらしいです。

https://developer.mamezou-tech.com/blogs/2023/05/18/deno-kv-on-deno-deploy/

「Deno deploy、流石に情報を記憶するサービスはしないか」と思っていたので驚きました。
結構夢が広がる機能・・・！