OmniAICreator/Qiita-1.07M huggingface dataset:
Github Pagesの使い方まとめ

# はじめに
Github Pagesを使うと手軽にWebサイトを公開することができます。
備忘録も兼ねGithub Pageの使い方をまとめていきたいと思います。

Github Pagesの詳細につきましては下記公式サイトよりご確認をお願いします。
[Github Pages公式サイト](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages)

# 手順
大まかに手順をまとめると以下の通りです。
1. 公開するWebページを作成
1. Githubに新しいリポジトリを作成する
1. 作成したリポジトリとローカル環境を連携する
1. リポジトリにファイルを追加する
1. コミット＆プッシュをする
1. Github Pagesの公開設定をする


## 1. 公開するWebページを作成
公開するWebページを作成し、PCに保管します。

## 2. Githubに新しいリポジトリを作成する
Githubアカウントにサインインして、画面右上の`+`のアイコンをクリックし、
New repositoryを選択します。
Githubアカウントをお持ちでない方は、[こちら](https://github.co.jp/)よりアカウントを登録します。
<img width="250" alt="your repository" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/51a48994-6cdd-3c92-6af5-a33c470798f7.png
">

Create a new repositoryの画面の `Repository name` にリポジトリ名を記入し、
画面下部の `Create repository`を選択します。
<img width="600" alt="create repository" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/581dbdb3-8b57-bb04-5ebf-31a02d3b5158.png
">

下図のような画面が表示され、リポジトリが作成できていればOKです。
<img width="600" alt="repository window" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/8321a8c9-096a-c1f8-7387-f97c99dad6e2.png
">

## 3. 作成したリポジトリとローカル環境を連携する
リポジトリ作成時の画面(上図)に記載のいずれかの方法を用いて、リポジトリとローカル環境を連携します。
今回は `..or create a new repository on the command line` の方法を使用します。

まず、ターミナルを開きます。
必要に応じて作業用フォルダに移動します。
(ここではホームディレクトリにtemplateというフォルダを作成し、作業を行う例を書きます)
```
$ mkdir template
$ cd template 
```

リポジトリ作成時の画面に書かれているコマンドをコピーし、実行します
```
$ echo "# template" >> README.md
$ git init
$ git add README.md
$ git commit -m "first commit"
$ git branch -M main
$ git remote add origin https://github.com/ユーザー名/template.git
$ git push -u origin main
```
これでリポジトリとローカル環境の連携は完了です。
ちなみに上記コマンドはREADME.mdファイルを作成・ファーストコミットをし、
リポジトリにプッシュしている動作となります。

## 4. リポジトリにファイルを追加する
作業フォルダにWebページに必要なファイルを追加します。

## 5. コミット&プッシュする
ファイルを追加したら、コミットとプッシュをします。
(ここではmainブランチに直接コミット、プッシュします)
```
$ git add .
$ git commit
$ git push origin main
```

## 6. Github Pagesの公開設定をする
Settingタブを選択します。
<img width="600" alt="Setting" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/d5c6258f-f600-4d75-e1f2-43f948b81fcf.png
">

左サイドバーにあるCode and automationの `Pages` を選択します。
<img width="200" alt="Select Pages" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/710e0928-1d68-ed72-42ec-5616c7b30ccb.png
">

Noneを選択し、公開用ブランチを選択します。
<img width="300" alt="Select Branch" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/4283bf2b-5e90-6571-517f-661ed63784c6.png
">

必要に応じてフォルダを設定し、`Save`を選択します。
<img width="300" alt="Select Branch" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3326710/25401305-763b-171c-a774-eaa58ee9e4a7.png
">

数分程度待つとデプロイされ、公開したWebページのURLが表示されます。
URLにアクセスすると、Webページを確認することができると思います。

# 最後に
以上がGithub Pagesを用いたWebページの公開手順となります。
Github Pagesは手軽にWebページを公開することができるツールです。
皆さんもぜひGithub Pagesを使って、Webページを公開されてみてはいかがでしょうか。

# 参考文献
[Github Pages公式サイト](https://docs.github.com/ja/pages/getting-started-with-github-pages/about-github-pages)
[ProgateのGithub Pages説明サイト](https://prog-8.com/docs/github-pages)
Discord のデフォルト画像保存先を変更する方法

## はじめに
Discord の画像を保存する際のデフォルトのダウンロードディレクトリを変更したかったので、レジストリを弄り変更してみました。この変更はシステム全体に影響します。つまり、すべてのアプリケーションがこの新しいダウンロードディレクトリを使用します。

## 環境
* Windows 10

## 導入

### レジストリの変更
1. 「Win」キー+「R」キーから"ファイル名を指定して実行"を開いて下さい。`regedit` と入力し"レジストリエディター"を開きます。
1. 「HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders」に移動します。
1. 「{374DE290-123F-4565-9164-39C4925E467B}」という名前のレジストリエントリを探します。これがダウンロードディレクトリのパスを指すエントリになります。
1. 右クリックして「修正」を選択し、新しいパスを入力します。

## 最後に
以上で、デフォルトのダウンロードディレクトリ先が変更されます。
Railsでの非同期化について

## この記事を書いた理由
RubyonRailsのサンプルやポートフォリオ作成時に
非同期化について勉強しましたがなんとなくのイメージで
非同期化 = おー、カッコイイ！！:heart_eyes:
このままではダメだと思ったのと、純粋に興味があったので書きたいと思いました。

## Ajaxの非同期化について
そもそも非同期化について深く理解する為にこちらの記事を参考にさせていただきました。
個人的にとても分かりやすいです。

https://pikawaka.com/word/ajax

## Railsで非同期化を実装
Rails 6.1.7.3

①まずは非同期化したい箇所を部分テンプレート化
②対象のviewファイルでidの設定とHtmlからJavascriptで読み込まれるように設定

```rb:show.html.erb
# 部分テンプレート適用ファイル
<div id="favorite_buttons_<%= @article.id %>">
<%= render "public/favorites/favorite", article: @article %>
```

```rb:_favorite.html.erb
# 部分テンプレートファイル
<%= link_to article_favorites_path(article), method: :post, remote: true do %>
```

idの設定(id="favorite_buttons_)ですが、これはコントローラで設定したアクション後に
Javascriptでこのidを頼りにviewを探しにいくので大切な設定です。
(区別化や一意性を目的として特定させるイメージ)

※ちなみにForm_withの場合は、自動でidが付与されるので不要。
(モデル名_カラム名がidになる。
モデル名がfavorite、カラム名がlikeだと、favorite_likeというidになる。)

またremote: trueのオプション設定することにより、viewの読み込みがHTMLからJavascriptに変わる。
ターミナルの表記が「Processing by ~ as HTML」から「Processing by ~ as JS」に変わればOK。

③コントローラでjsファイルを読ませる為に、アクション後のredirect_toはコメントアウト。
これでアクション内にrenderもredirect_toもない場合は
「app/views/コントローラ名/アクション名.js.erb」を読み込むようになる。
renderを用いた場合は指定した名前のjs.erbを読み込みます。

```rb:sample
def create
    @article = Article.find(params[:article_id])
    favorite = current_user.favorites.new(article_id: @article.id)
    favorite.save
    # redirect_to article_path(article)
end
```

④js.erbを作成する
(例)
* app/views/favorites/create.js.erb
* app/views/favorites/destroy.js.erb

⑤コードを記述する
```rb:create.js.erb
$('#favorite_buttons_<%= @article.id %>').html("<%= j(render "public/favorites/favorite", article: @article) %>");
```

この$()のカッコ内をセレクタで今回は#favorite_buttons_を指定してます。
※ちなみに「#」がidを意味しており「.」にするとクラス要素にできる。

<%= %>を用いて@article.idを記述。
この@articleは、コントローラのcreateアクション内で定義された@articleです。

.html(~)でビューで部分テンプレートを呼び出すのと同じ記述。
j()はescape_javascript()の省略形。
js.erbファイルで部分テンプレートを呼び出す際に必要な書き方。

これでコントローラを通って最新の状態になったインスタンス変数を用いて、
部分テンプレートで書き換える、という動作になる。

以上となります。

間違いや修正があれば対応していきます。
最後までありがとうございました。
【AWS】Kinesisの種類

# はじめに
Kinesisの種類についてのまとめです。
Kinesisは、リアルタイムデータストリーミングを実現するAWSのマネージドサービスであり、以下の3つの異なる種類があります。

## 1. Amazon Kinesis Streams
Amazon Kinesis Streamsは、最初にリリースされたKinesisサービスであり、データの収集、処理、分析をリアルタイムで行うための基本的なストリーミングプラットフォームです。Kinesis Streamsは、シャード（データのパーティション）を使用してデータを分割し、高いスループットとリアルタイム性を実現します。データはストリーム内で順序を保持して処理され、複数のアベイラビリティーゾーンに分散保存されるため、耐久性と信頼性が高いです。Kinesis Streamsは、独自のデータ処理アプリケーションや他のAWSサービス（例：Lambda、Kinesis Data Analytics）と統合して使用することができます。

## 2. Amazon Kinesis Firehose
Amazon Kinesis Firehoseは、データのストリーミングとデータの配信を簡素化するためのサービスです。Kinesis Firehoseは、データをストリームに送信し、リアルタイムで処理した後、指定したデータストアやデータウェアハウス（例：S3、Redshift）に直接データを配信します。Firehoseは、ストリームからのデータ受信とデータの配信に関する複雑さを取り除き、データの配信先の設定と管理を容易にします。また、データの変換や圧縮、暗号化などのデータ前処理も自動的に行うことができます。

## 3. Amazon Kinesis Analytics
Amazon Kinesis Analyticsは、リアルタイムデータストリームからのデータ分析を簡単に実現するためのサービスです。Kinesis Analyticsは、SQLクエリを使用してストリーム内のデータをリアルタイムで分析し、データの集計やパターンの検出、トレンドの分析などを行うことができます。Kinesis Analyticsは、ストリームからデータを読み取り、指定したSQLクエリに基づいてデータを処理し、結果を指定した先（例：Kinesis Streams、S3）に出力します。これにより、リアルタイムでのデータ分析と洞察を簡単に実現できます。

## まとめ(使い分け)
Kinesis Streamsは、高いスループットとリアルタイム性が必要な場合。
Kinesis Firehoseは、シンプルなデータのストリーミングと配信を必要とする場合。
Kinesis Analyticsは、リアルタイムデータの分析と洞察が求められる場合。
チャットGPTを使ってニーズに合った最新のAIツールをリストアップしてもらう方法

チャットGPTのプラグインすごいですね。

既にご存じの方もおられるとは思いますが、今回は欲しいAIツールをチャットGPTにリストアップしてもらう方法についてです。

チャットGPTのプラグインの中に

「theres an ai for that」

というものがあるのでそれを入れるだけです。

![rapture_20230520124131.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340833/a0d33c84-9fb2-81a5-af2c-4a656f71d880.jpeg)

ちなみにこのサイトは世界最大のAIデータベースということです。

https://theresanaiforthat.com/

これがチャットGPTとプラグイン連携したということですね！

実際に入力している画面です

![rapture_20230520123851.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3340833/eabd69c4-275b-ba46-b5fc-1759934ba194.jpeg)


僕は以前からこのサイトでAIツールリサーチをしてましたが、
何が嬉しいのかというと、

・世界最大のAIデータベースを日本語で検索できるようになった

・プロンプトでGPTが探してくれるのでキーワード検索よりも便利！

・AIツールリサーチが爆速にできるようになった！

という感じです。

使いこなしてみて下さい～。
便利なhas_secure_password

has_secure_passwordとは?
---------------------------------------

パスワードを暗号化して保存してくれます。めっちゃ便利！！
使い方は、まずモデルに定義する。
~~~user.rb
class User < ApplicationRecordclass 
  .
  .
  .
  has_secure_password
end
~~~
モデルにこのメソッドを追加すると、次のような機能が使えるようになる。

has_secure_passwordの便利機能
---------------------------------------

<ul>
　<li>セキュアにハッシュ化したパスワードを、データベース内のpassword_digest属性に保存できるようになる。

 <li>2つの仮想的な属性（passwordとpassword_confirmation）が使えるようになる。また、存在性と値が一致するかどうかのバリデーションも追加される。

<li>authenticateメソッドが使えるようになる（引数の文字列がパスワードと一致するとUserオブジェクトを返し、一致しない場合はfalseを返すメソッド）。
</ul>

条件
---------------------------------------
__has_secure_password機能を使えるようにするには、モデル内にpassword_digest属性が含まれてる必要がある。暗号化されたパスワードはpassword_digestというカラムに保存されるので、同一名称のカラムを用意しておく必要があります。__

参考:[Ruby on Railsチュートリアル](https://railstutorial.jp/)
JUnitまとめ

# JUnitとは  
Javaの単体テスト用フレームワーク。単体テストを効率よく実施するためのもの。

## メリット  
* テスト実行を自動化できる
* テストコードを仕様・ソースの理解に利用できる
* 問題を早期発見できる。  
etc..

## デメリット
* 関連ツールやライブラリの知識が必要
* テストコードの実装に時間がかかる
* Junitの仕組みでは、向いていないテストがある  
etc..

# springでのtest
src/test/java～に作成したテストクラスを格納する。
* テスト対象クラスの同一パッケージ配下にテストクラスを作成
* デフォルトではSpringBootApplicationクラスに対応するテストクラスが
* テストクラスの命名は、「テスト対象クラス名 + Test」となる。

## spring-boot-starter-test
spring-boot-starter-testを追加する事で使用できるライブラリ（代表的なもの）
* JUnit5

以下モジュールで構成される単体テストフレームワーク。

・Junit Platform:テストフレームワークを起動するための基盤

・Junit Jupiter:Junit5のことを指し、TestEngineを提供

* Spring Test & Spring Boot Test

Spring Bootベースアプリケーションのテストを実行するために必要なライブラリ群

MockMVCという、Tomcatを起動させない状態でも、Springの動作を再現することができるフレームワークを持つ

* AssertJ

Junitで値を検証するときに使用するライブラリ。

## 書き方
@SpringBootTestを利用することで、SpringBootアプリケーションの検証を行うことができる。

JUnit5の書き方に従い、AssertJを利用した値の検証を記述することができる。
~~~ java
@SpringBootTest
class SpringitemApplicationTests {

	@Autowired
	private ItemController itemController;
	
	// アプリケーションがSpringコンテキストを正常にロードできたかどうかを検証する。
	@Test
	void contextLoads() {
		//AssrtJを利用した検証を実装する
		//assertThatの引数に検証の値を入れる
		//続けてメソッドにて期待値を指定。この場合はNullでないこと
		
		//itemControllerが@Autowiredによって、自動でインスタンス化されてNullでないことを確認する。
		assertThat(itemController).isNotNull();
	}
~~~
* @SpringBootTest

テストクラスにてSpring Bootの機能が利用できるようになる。

コンソール上、SpringBootが起動しているように見えるが、Tomcatサーバは起動していない。

* @Test

Junitがテストケース（テスト項目表の１テストケースに対応するイメージ）として管理する。

AssertJの機能を用いて値を検証する。asserThat(テスト項目).メソッド(期待値)という形式で、テスト項目がNULLでないことを確認する。

期待値と異なっていた場合は、単体テストNGとしてJunitが管理する。

### MockMVCを用いたテストケースの書き方
MockMVCを使用すると、アプリケーションサーバが起動していない状態においても、Springアプリケーションの動作を再現させることができる。

Controllerのテストを行う際に利用。

~~~ java
@SpringBootTest
@AutoConfigureMockMvc
class ItemControllerTest {
	
	@Autowired
	private MockMvc mvc;

	
	//検索結果が想定通りであるかを確認するテスト
	@Test
	void testGetItem() throws Exception{
		int itemId = 1;
		String responseJsonString =mvc.perform(get("/items/{itemId}",itemId)
				.contentType(MediaType.APPLICATION_JSON)
				.accept(MediaType.APPLICATION_JSON_UTF8_VALUE) //非推奨であるが現時点では入れる必要がある。
				.characterEncoding("UTF-8"))
				.andExpect(status().isOk()) //ステータスコードチェック
				.andReturn().getResponse().getContentAsString();
		// 取得したJsonオブジェクトをJavaオブジェクトにマッピング
		ObjectMapper objectMapper =  new ObjectMapper();
		Item responseItem = objectMapper.readValue(responseJsonString, Item.class);
		
		//各値を比較する
		assertThat(responseItem.getItemId()).isEqualTo(1L);
		assertThat(responseItem.getItemName()).isEqualTo("ネックレス");
		assertThat(responseItem.getItemCategory()).isEqualTo("ジュエリ");
	}

}
~~~

* @AutoConfigureMockMvc
@AutoConfigureMockMvcアノテーションを付加すると、MockMVCが自動構成され、@Autowiredアノテーションで利用することができるようになる。

* MockMvc.performメソッドを利用して、HTTP GET等のAPI呼び出しを再現し、動作を検証する事ができる。

# 参考ハンズオン
https://www.udemy.com/course/spring-bootrest-api/
【DB設計 初心者が躓いたポイントまとめ】

DB設計難しいですよね。
初心者が躓くポイントや疑問に思ったポイントがいくつかあります。
今回は、それらのポイントを整理し、解決策を提案します。
なお、解決策は基本的にチャットGPT先生に教えてもらいました。

##### Q1. テーブル作成する時に同時にデータを入れるのはマストで必要？

テーブル作成時にデータを同時に挿入する必要はありません。通常はまずテーブルを作成し、その後別のクエリを使ってデータを挿入します。データのみ後で入れることも可能です。

##### Q2. テーブル作成はどの場所で行えば良い？

データベースに接続しているコマンドラインクライアント（コマンドプロンプト）や、グラフィカルなデータベース管理ツール（phpMyAdmin、MySQL Workbench など）で実行できます。

##### Q3. プライマリーキーって何？

プライマリーキーは、各レコードが一意になるようなキーのことを指します。

##### Q4. テーブル定義はテーブル作成の時しかできない？

テーブル定義は、テーブル作成時に初めて設定されますが、その後も変更することができます。テーブル定義を変更するためには、ALTER TABLE コマンドを使用します。

##### Q5. テーブル作成時にデータ型は必須か？

はい、データ型は必須です。データ型を設定することで、そのカラムに格納できるデータの種類と形式が定義されます。

##### Q6. 制約を決めたらどうやってそれを守らせるのか？

制約を適切に設定することで、データベースが不適切なデータの挿入や更新を防ぐ役割を果たします。

##### Q7. CHAR型とVARCHAR型をどうやって使い分けるのか？

CHAR 型と VARCHAR 型の使い分けは、データの性質と必要なストレージ容量によって決まります。一般的には、長さが一定であるデータには CHAR 型を、長さが可変であるデータには VARCHAR 型を使用します。

##### Q8. 文字列型のカッコの中に入れる文字列の長さはどうやって決めるのか？

カラムの文字列長は、そのカラムに格納されるデータの最大長に基づいて決定します。

##### Q9. 各テーブルの主キーは数字だけの方がいいのか？

各テーブルの主キーは、数値だけでなく文字列を含めることも可能です。どちらがより適切かは、データベースの設計や使用目的に依存します。

##### Q10. スプレッドシートとSQLの違いは何か？

スプレッドシートは小～中規模のデータを簡単に管理するためのツールで、一方SQLは大規模なデータを効率的に管理、操作、分析するための言語です。

##### Q11. ボイスコッド正規形とは何か？

ボイスコッド正規形とは、非キーから主キーへの関数従属をなくすことを指します。

##### Q12. 正規形の本質とは何か？

正規形の本質は、データの更新時の問題を避けることです。データベース設計時に正規形を適用することで、データの更新、挿入、削除が行われたときに、データの一貫性や整合性を保つことが可能となります。


##### Q13: ER図はどのカラムがどれに対応しているかまでは分からないのか？

A: ER図では、各エンティティ（テーブル）のカラムとそのデータ型が記載されていますが、具体的な値やどのカラムがどのデータに対応しているかは分からないことが多いです。ER図の主な目的は、データベースの構造やエンティティ間のリレーションシップを視覚化することです。


##### Q14: ER図のエンティティは第1正規形でも構わないのか？

A: ER図を作成する際には、データベースの正規化を考慮してエンティティを設計します。第1正規形は、エンティティ内の各カラムが原子的な値（分解できない値）を持つことを要求します。原子的な値を持つカラムを設計することが推奨されますが、一部のケースでは非正規化（第1正規形を満たさない形）が許容されることもあります。


##### Q15: ER図にテーブル定義の情報は書いてはいけない？

A: 通常、ER図にはテーブル間のリレーションシップや主要な属性（カラム）が書かれますが、すべてのテーブル定義の情報を記載することは珍しいです。ER図は主にデータベースの構造やテーブル間の関連性を視覚化するためのものであり、詳細なテーブル定義情報は別の文書やファイルに記述されることが一般的です。


##### Q16: テーブル定義は空欄でも構わない項目もある？

A: はい、テーブル定義で空欄でも構わない項目は存在します。例えば、初期値（デフォルト値）、外部キー制約、ユニークキー制約、AUTO INCREMENTなどがその例です。しかし、テーブル名、カラム名、データ型、NULL許容性（NULL YES or NO）は、すべてのカラムに対して必ず設定する必要があります。これらは、テーブル定義の基本的な要素であり、データベースシステムが正しく動作するために必要です。
GitHubで特定コミット,ブランチの差分を確認する方法

## 概要

GitHubのGUI上で、特定コミット同士の差分を確認する方法を備忘録として残しておきます。特定ブランチ同士の差分の確認方法も合わせて記載しておきます。

## 結論

特定コミット同士の差分確認方法
```
https://github.com/[ユーザー名]/[リポジトリ名]/compare/[コミットID①]...[コミットID②]
```

特定ブランチ同士の差分確認方法
```
https://github.com/[ユーザー名]/[リポジトリ名]/compare/[ブランチ名①]...[ブランチ名②]
```

## 特定コミット同士の差分確認方法の詳細


例として、私のgithubのリポジトリで確認してみます。コミットIDが`99c7f45`と`f7da013`の差分が確認できるようになっていると思います。
https://github.com/Shota0616/docker_django/compare/99c7f45...f7da013

コミットIDは以下の赤枠の部分を押下すると
![スクリーンショット 2023-05-20 12.09.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620245/ab32926d-3947-17c1-8374-dde7cf527469.png)
下の画面に遷移して赤枠の中がコミットIDになります。
![スクリーンショット 2023-05-20 12.09.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2620245/3041a4fd-8e62-dc0c-12a7-42bea4fd0a68.png)


## 特定ブランチ同士の差分確認方法の詳細

こちらも例として私のリポジトリで確認してみます。ちょっと下の例だと差分無いですが、差分があるブランチ同士だと差分が出るはずです。
https://github.com/Shota0616/docker_django/compare/main...feature
private extensionでクラスや構造体を分割する(Swift)

## はじめに

private extensionでクラスや構造体を分割するパターンを紹介します。

## 環境

- OS：macOS Ventura 13.3.1 (a)
- Xcode：14.3 (14E222b)
- Swift：5.8

## 分割前

以下のようなSwiftUIのViewがあります。

```swift:SakatsuInputView.swift
struct SakatsuInputView: View {
    var body: some View {
        Form {
            generalSection
            forewordSection
            temperaturesSection
        }
    }

    private var generalSection: some View {
        // ...
    }

    private var forewordSection: some View {
        // ...
    }

    private var temperaturesSection: some View {
        // ...
    }
}
```

各セクションは他のクラスや構造体から呼ばれないので `private` を付けています。

このままでも問題ないですが、Viewのプロパティやメソッドが他から呼ばれることは基本的にないので、わざわざ `private` を付けるとかえってノイズになるという意見もあります。

でも私は他から呼ばれないことを保証したいです。

そんなときにprivate extensionが使えます。

## 分割後

private extensionを作成し、各セクションを移動しました。

private extension内のプロパティやメソッドは、他のファイルから呼べません。
そのためプロパティやメソッドから `private` を外すことができます。

```swift:SakatsuInputView.swift
struct SakatsuInputView: View {
    var body: some View {
        Form {
            generalSection
            forewordSection
            temperaturesSection
        }
    }
}

// MARK: - Privates

private extension SakatsuInputView {
    var generalSection: some View {
        // ...
    }

    var forewordSection: some View {
        // ...
    }

    var temperaturesSection: some View {
        // ...
    }
}
```

ノイズが排除され、さらにextensionでグルーピングすることで元の構造体がスッキリしました。

## 注意: private extensionはfileprivate

private extensionはfileprivateなので、同一ファイルからだと呼び出せてしまいます。

```swift
struct Foo {}
private extension Foo {
    func foo() {
        print("Foo")
    }
}

struct Bar {
    func bar() {
        Foo().foo() // !!!: 他の構造体からprivate extension内のメソッドが呼び出せる
    }
}

Bar().bar() // "Foo"
```

そのため、できる限り1ファイル1クラス・構造体にするのが望ましいです。

## おわりに

好みもありますが、私はSwiftUIのViewでは積極的にprivate extensionで処理を分割しようと思いました。

分割しない場合は、中途半端に `private` を付けると混乱するので、 `private` を付けるなら他から呼ばれないすべての処理に付ける（もしくはすべてに付けない）よう統一するのが望ましいです。

## 参考リンク

- https://twitter.com/the_uhooi/status/1641597080753025024
- [Refactor privates by uhooi · Pull Request #155 · uhooi/Loki](https://github.com/uhooi/Loki/pull/155)
Slack APIを使ってファイルをアップロードする curl ワンライナー編

### サンプル

test.pngをアップロードするサンプル。

```
curl \
-F "file=@test.png" \
-F "initial_comment=initial comment" \
-F "channels=C01XXXXXX" \
-H "Authorization: Bearer xoxb-xxxxxxxxxx" \
https://slack.com/api/files.upload
```

標準入力から受け取った中身をアップロードするサンプル。
以下ではLinuxのスクショをImageMagickのimportコマンドを使ってアップロードする。

```
import -window root png:- | curl -F "file=@-" -F "initial_comment=initial comment" -F "channels=C01XXXXX" -H "Authorization: Bearer xoxb-XXXXX" https://slack.com/api/files.upload
```

### 以下パラメータの取得方法

#### チャンネルIDの取得方法は？

Slackの投稿の「CopyLink」で投稿の直リンクを取得

```
https://rooter.slack.com/archives/C0XXXXXXX/p16XXXXXXXXXXX
```

この`C0XXXXXXX` がチャンネルリンク

#### Authorizationの取得方法

Slackのアプリケーションは作られてる前提。でアプリケーション一覧→アプリを選択→Oauth & Permisshon → BotUser Oauth Tokenから取得して、Authorization: Bearer の後のパラメータにそのままセットすればOK。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/3430a339-cada-ce9f-e421-f012199cb4cd.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/2abb2e5f-7346-a4a4-bf0e-0033fdd8756f.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/a6d2b363-b93a-5460-0164-dd2e0efbab24.png)

### なぜ curlで実装 ？

- SlackのAPIリファレンスがcurlだから
- curlコマンドが使える環境はめちゃ多い
- curlが読めないプログラマーなどいない
- スクショをパイプを使ってファイルを介さずに投稿するワンライナーとかめちゃくちゃかっこいい
Emacs org-mode で特定の画像の表示を制御する(ChatGPT執筆)

# はじめに(ここは人間が書いてます)
org-modeで困ってた課題をChatGPTに質問したらelispまで書いてくれました。
その内容を記事にしようと思ったんですが、記事を書くのも面倒くさかったので、ChatGPTにお願いしました。
以下、ChatGPTが書いた記事を載せます。
内容が動作することは少なくとも私の手元では確認済みです。
あとChatGPTを使った記事をqiitaに投稿することは、探した範囲では禁止ではないようでした。




タイトル: **Emacs org-mode で特定の画像の表示を制御する**

# 課題

Emacs の org-mode を使ってドキュメンテーションを行う際、時折、画像のインライン表示を有効にする必要があります。これは `org-toggle-inline-images` コマンドを使用することで実現できます。

しかし、このコマンドを使うとドキュメント中の全ての画像が表示されてしまいます。特定の画像のみを表示したい場合には、やや使いづらいという課題がありました。

この記事では、この課題を解決するための方法を提案します。

# 解決策

特定の画像のみを表示するための組み込みの機能は org-mode には存在しないため、自身で解決策を実装する必要があります。以下に、その方法を2つ提案します。

## 方法1: 一時的に他の画像をコメントアウトする

特定の画像のみを表示したい場合、一時的に他の画像のリンクをコメントアウトすることができます。コメントアウトされた画像は `org-toggle-inline-images` コマンドで表示されません。

この方法の欠点は、コメントアウトを元に戻さなければならないことです。長いドキュメントや多数の画像が含まれるドキュメントの場合には手間がかかります。

## 方法2: サブツリー内の画像の表示を制御するカスタムコマンドを作成する

Emacs Lisp (Elisp) を使用して、特定の画像を表示/非表示するための新たな関数を作成することもできます。以下にその一例を示します:

```lisp
(defun org-toggle-inline-images-in-subtree ()
  (interactive)
  (save-excursion
    (save-restriction
      (org-narrow-to-subtree)
      (org-toggle-inline-images)
      (widen))))
```
この関数を評価した後、表示したい画像があるサブツリーにカーソルを置いて `M-x org-toggle-inline-images-in-subtree` を実行します。これにより、そのサブツリー内の画像のみが表示されます。

# まとめ

Emacs org-mode の `org-toggle-inline-images` コマンドは、ドキュメント全体の画像表示を切り替えるための便利なツールですが、特定の画像のみを表示する方法は組み込まれていません。

この記事では、画像のコメントアウトや新しい Elisp 関数の作成など、特定の画像の表示を制御するための方法を提案しました。これらの方法を利用すれば、org-mode でのドキュメンテーション作業がより柔軟になり、特定の画像の表示制御も可能になります。

これらの方法が完全な解決策ではないかもしれませんが、org-mode の利便性を高める一助となることを願っています。これからも Emacs のパワフルなカスタマイズ機能を駆使して、より効率的なドキュメンテーション環境を目指しましょう。

Happy Hacking!
x0tigervncserverをsystemdでboot時に起動する設定

# 経緯
## 実現したかったこと

systemd で boot 時に `x0tigervncserver` コマンドを自動的に起動して、Windows PCからリモートデスクトップで接続したい。

そうすれば、linuxのデスクトップ上で作業していたことをリモートから引き続き作業できる。
（wiresharkで解析中に中断して別の場所へ移動したときとかに便利）

## 悩んだこと

複数の日米のサイトで、下記の一行を使って systemd から起動する例として、
~~~
ExecStart=/bin/sh -c 'sleep 10 && /usr/bin/x0vncserver -display :0 
 &'
~~~
が示されていたのですが、自分の環境ではうまく動作しませんでした。

/home/oralton/.vnc 下のログで
~~~
 Geometry:    Desktop geometry is set to 1920x1080+0+0
 XDesktop:    Using evdev codemap
 XDesktop:
 XDesktop:    XTest extension present - version 2.2
 Main:        Listening on port 5900
3NI3X0 New X0tigervnc server 'hoge:0 (oralton)' on port 5900 for display :0.
3NI3X0 Use xtigervncviewer -SecurityTypes VncAuth -passwd /home/oralton/.vnc/passwd :0 to connect to the VNC server.
Killing X0tigervnc process ID 4342... Main:        Terminated
 success!
~~~
のように、「killing ....」の行で起動直後に終了してしまっていました。

## 環境

- 古めのノートPC
- "Debian GNU/Linux 11 (bullseye)
- display manager: Gnome (bullseyeインストール時のdefault設定のまま)
- xrdp 導入済み
- デスクトップへの autologin 設定済み

## 解決の要点

- ExecStart の中で `x0tigervncserver &` でbackground起動していたのが駄目だったようです。
- ついでに ExecStartPre を活用して sleep は別の行に記述します。


# 実践
## 設定
vim /etc/systemd/system/x0tigervncserver.service に以下を記述しました。

~~~
[Unit]
Description=x0tigervncserver (mirroring about disp:0)
After=network.target gdm.service
Requires=gdm.service

[Service]
SyslogIdentifier=x0tigervncserver
Type=forking
User=oralton
Group=oralton
WorkingDirectory=/home/oralton
ExecStartPre=/usr/bin/sleep 30
ExecStartPre=/usr/bin/echo "hello! xrdp!!"
ExecStart=/usr/bin/x0tigervncserver -display :0 -rfbport 5900 -passwordfile /home/oralton/.vnc/passwd

[Install]
WantedBy=multi-user.target
~~~

## 簡単に動作確認

※　xrdpやデスクトップへのオートログインは設定済みです。

このため、
~~~
systemctl daemon-reload
systemctl start x0tigervncserver.service
systemctl enable x0tigervncserver.service
reboot
~~~
としてから、
Windows PCでリモートデスクトップ接続して動作確認できました。
[Unity] 汎用的な自動参照機能を作りたかった

# 概要
表題の通り
実装だけ見たい方は[こちら](https://github.com/riru-ruribe/Refmatic)

# 経緯
#### 起
運用フェーズに入ってからの改修について、実装の時点である程度考えておかないと後々大変になることがある

例えば、カードの属性を追加したいとなった場合、一般的に以下のような修正が考えられる
- カードのサムネイルに属性画像などを追加
- 能力値の計算方法などを追加
- etc...

#### 承
スクリプト側の修正は軽微であったが、アセット側の修正に難があった
各シーンやプレハブが各々でアセットの参照を持っていたため、全ての実装を調査しないといけなかった

※宣言しているフィールド名がバラバラ、インナークラスで実装もあり型宣言がバラバラ（一般化できない）
※ScriptableObjectでまとめるという発想はない

#### 転
そこで自動参照ができれば楽になりそうと思い、特定のフォルダに対してアセットが追加された場合に、フォルダ内のアセットを参照しているアセットに対して追加されたアセットを自動的に足すことを考えた

日本語だと分かりづらいので具体例を出すと、このようなフォルダ階層だった場合（~~本来はもっと深い階層になりそうだが~~）
```
Assets
  ∟ Attributes
    attirbute_icon_01.png
    attirbute_icon_02.png
  ∟ ...
```
1. Attributesフォルダにattirbute_icon_03.pngを追加した
2. 01,02を参照しているアセット（シーンやプレハブ）に03の参照が追加される

となる

<details><summary>スクリプト側は以下のように属性を使う</summary><div>

```c#
[RefmaticElementLoad("attirbute_icon_", RefmaticComparisons.StartsWith, "Assets/Attributes/")]
[RefmaticExecutableLoad]
[SerializeField]
Sprite[] sprites;
```
パスを指定するので、（スクリプトだけ見て）アセットがどこにあるかが分かるという副次的な利点も生まれた
</div></details>

#### 結
経緯の説明はあくまで一例で、他にもいろんなパターンがあると思う

~~そんなに頻繁に使う機能ではないが~~、とにかく拡張性を高くしてやれることの幅を広げた...つもり
Powershellでワンライナー(特定日時以降のファイルを操作)

# はじめに
今はバッチで色々スクリプト組んでますが、やりたいことを簡単に実現させたいので(1行で貼りつけるだけで簡単にできるので楽)

# ワンライナー
```powershell:AfterFileOperation.ps1
# 特定日時以降のファイルをコピー
Get-ChildItem "C:\wakasama\wakasama\bak" | Where-Object { $_.LastWriteTime -gt (Get-Date).AddMinutes(-((Get-Date) - (Get-Date "2023/01/01 12:34:56")).TotalMinutes) } | Where-Object { Copy-Item $_.FullName "C:\wakasama\wakasama\test\." } 

# 特定日時以降のtxtを削除
Get-ChildItem "C:\wakasama\wakasama\test" | Where-Object { $_.LastWriteTime -gt (Get-Date).AddMinutes(-((Get-Date) - (Get-Date "2023/03/01 12:34:56")).TotalMinutes) -and $_.Name -like "*.txt" } | Where-Object { Remove-Item $_.FullName } 
```

# 参考サイト
◆Powershellで更新時間が数分前のファイルの削除方法 : 中小企業社内SEのメモ
　http://blackpage.blog.jp/archives/1079132486.html
◆PowerShell(日付時刻の計算) | コマンドの達人
　https://life-is-command.com/powershell-get-date/
◆【PowerShell】ファイルの作成日時や更新日時を取得する - ほそぼそプログラミング日記
　https://hosopro.blogspot.com/2016/11/powershell-get-itemproperty.html
◆多くのディレクトリの中にある、それぞれのファイルを一つ上のディレクトリにコピーする
　https://qiita.com/kmr_hryk/items/5fdfe97e7c98ab9cbe17
react-particles-jsからreact-tsparticlesへの変更手順

`react-particles-js`ライブラリが非推奨となっていたため`react-tsparticles`に変更しました。その方法を簡潔にまとめてみます。

***

# `react-particles-js`のアンインストール
```bash
$ npm uninstall react-particles-js
```

# `react-tsparticles`をインストール（バージョン1.43.1）
最新のv2だとなぜか表示されなかったので`v1.43.1`を。

```bash
$ npm i react-tsparticles@1.43.1
```

# `import Particles from 'react-tsparticles'`の置換
すべての`import Particles from 'react-particles-js'`を`import Particles from 'react-tsparticles'`に置き換えます。

```diff_javascript
-import Particles from 'react-particles-js'
+import Particles from 'react-tsparticles'
```

# オプション設定の追加
`react-tsparticles`では**デフォルトでページ全体に適用されてしまう**ため、コンテナ内のみに適用する場合はパラメーター内に以下のオプション設定を追加します。
```bash:tsparticles-config.json
{
# 他のオプション ,
"fullScreen": {
"enable": false
},
# 他のオプション ,
}
```
# おまけ
particleのデモのリンクをいくつかご紹介します。
以下のサイトではさまざまな操作が可能ですが、バージョン1では動作しない場合があるかもしれません。

https://vincentgarreau.com/particles.js

https://particles.js.org/samples/index.html
RasbianOS(32bit) 上で go コマンドを実行すると以下のようなエラーになります。$ go -bash: /opt/go/1.20.4/bin/go: No such file or directory

カーネルのバージョンと、ユーザランドでビットサイズが違ってもいいなんて知らなかった。

- [Userland interfaces — The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/gpu/drm-uapi.html)

> Compatibility handler for 32 bit userspace running on 64 kernels

- [ioctl based interfaces — The Linux Kernel documentation](https://www.kernel.org/doc/html/latest/driver-api/ioctl.html)

> In order to support 32-bit user space running on a 64-bit machine

---

RasbianOS(32bit) 上で go コマンドを実行すると以下のようなエラーになります。

```bash
$ go
-bash: /opt/go/1.20.4/bin/go: No such file or directory
```

file コマンドで確認すると、ファイル自体は存在しているようです。

```bash
$ file $(which go)
/opt/go/1.20.4/bin/go: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-aarch64.so.1, Go BuildID=jvXjoLxCSBfOUTuSIVkf/__5mSsz9XUrphdoRVSnC/iQUlMsirBZkSHT9hsoxY/TFMhRuiUZonbX61yxf9k, with debug_info, not stripped
```

ビットサイズが32ビットのユーザランドでビットサイズが64bitの実行ファイルを実行しようとすると、ビットサイズによるエラーではなく `No such file or directory` というエラーが出力されるということはありますか?

なお、RasbianOS(32bit)を使っていることは `getconf LONG_BIT` で確かめました。

```bash
$ getconf LONG_BIT
32
```

arch コマンドで確認したところ、カーネルのビットサイズは64ビットとなっていました。

```bash
$ arch
aarch64
```

---

Raspbian OS（32ビット）では、32ビットのユーザーランドで64ビットの実行ファイルを実行することは一般的にはできません。この場合、エラーメッセージに「No such file or directory」が表示されるのは、実行ファイルが見つからないためです。

Raspbian OSが32ビットの場合には、32ビット版のGoバイナリを使用する必要があります。64ビット版のGoバイナリを使用すると、エラーが発生します。

Go言語の公式ウェブサイトから正しいバージョンのGoをダウンロードし、32ビット版のバイナリをインストールしてみてください。それによって、この問題は解決するはずです。

また、カーネルのビットサイズが64ビットであっても、ユーザーランドが32ビットの場合は、ユーザーランドのビットサイズに従って実行ファイルを選択する必要があります。
【AWS】Cloudfrontを用いて海外からのアクセス制御する方法

AWSを用いて海外からのアクセス制御を実行するにはいくつか方法があるが、今回はCloudfrontを用いたアクセス制御方法を。


# Cloudfront
![スクリーンショット_2023-05-20_9_12_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779582/a8e04930-0a22-3346-eb1e-cc89ec1703b9.png)
作成したディストリビューションを選択し、［地理的制限］タブをクリック。

![スクリーンショット_2023-05-20_9_20_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779582/73884e9b-2267-a390-b989-804c9c3069ef.png)
編集をクリック。

![スクリーンショット_2023-05-20_9_20_47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779582/95567909-0000-1b1e-a121-2af4b19ba879.png)
- 制限なし
- 許可リスト
- ブロックリスト

の3択から選べる形式。
「許可リスト」・「ブロックリスト」を選択すると、国を選択することができ、どこの国からのみアクセス可、またどこの国からのみアクセス不可といった設定ができる。

![スクリーンショット_2023-05-20_9_26_36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779582/2d641636-4926-a343-2d4a-e0336b2cf254.png)
上記の例だと、日本とアメリカのみアクセス可という設定になる。
［変更を保存］をクリックすることで、本設定が適用される。
bashの非省略名称＋rcの意味

# bashの非省略名称など

`bash`のshはシェルのこと。 shが開発者の名前にちなんで「Bourneシェル」と呼ばれることに対し、「Bourne Again SHell」を略して `bash`.

# rcの意味

これについては、Qiitaにありました。ブログ投稿ありがとうございます。

https://qiita.com/turmericN/items/dc62c06dce773ec41133

rc = run commands です

# bashはバッハっじゃない

どうでもいいこと！

Bach, bash ですごい似ている。

```
vi .bachrc
```

ってうっちゃうと、エラーがでるので注意。心の中でバーンアゲンシェルランコマンドって唱えながらタイプするといいかも。
Proxmox7 を試してみる　その４　AlmaLinux8(migration)

# Vmware Workstation16 からのお引越し
vmware WorkstationにあるAlmaLinux8(CentOS8同等)を、Proxmox 7.4 に migration(お引越し)してみます。単にそれだけでもすこしはまりました。


# OVFエクスポートする際の注意
Vmware WorkstationのVMを選択してOVFメニューが活性化されないケースがあります。この理由は、該当VMが暗号化指定されているためOVFエクスポートができないためです。ですので強制的に vmdk を Proxmox にもっていっても、qm でコンバートできないとエラーになります（理由がわからず、割とはまった）。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/1787ce33-e6b1-4914-4d53-35e9ba085221.png)

# Proxmoxで OVFインポート作業
OVFエクスポートで出力された ovf/mf/vmdk の３ファイルを Proxmox にssh転送します（手順は割愛）。Proxmox のコンソール(root) で以下のコマンドを実行する。
このとき id として指定するのは、作成済み id を指定すると怒られるので注意する。

書式：qm importovf id xxx.ovf local-lvm --format qcow2

下記コマンドでは、id=111 を指定している。

```text
# qm importovf 111 almalinux.ovf local-lvm --format qcow2
```

# ProxmoxでのVM状態
qm コマンドでインポートが成功すると Proxmox の VM が生成されます。
下記がデフォルトの状態。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/e36a38e2-affe-2da2-a7bc-246639bf9b99.png)

この状態で起動してみる。と。`dracut` プロンプトになってしまい起動してこない。
・[VirtualBoxからProxmox VEに仮想マシンを移行した話](https://qiita.com/tomgoodsun/items/e8ff6dc8d6679c0fe4c7)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/cb0b30fb-99b9-09a6-fa97-3a9172830c70.png)

# ハードディスクをideに変更すると起動できた
ハードディスクが認識できないのではとぐぐってみた結果、ビンゴでした。ideに変更するといいらしい。
・[VM Migration Issue - LVM on CentOS 7 Guest](https://forum.proxmox.com/threads/vm-migration-issue-lvm-on-centos-7-guest.24953/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/0ffe71d6-0b6a-3808-6e8d-bfc7c22030a5.png)

くるか？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/6801dda7-b366-e733-2772-e9c78b159995.png)

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

# 最終的な結果
若干ide・・・と気にはなるものの migration できることが目的なので結果よし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/bc07f9ea-1073-0e4f-4d03-af09c8303acf.png)

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

・[仮想化基盤の Proxmox VE への移行](https://blog.nnstt1.dev/posts/2022/07/29/proxmox-migration/)
・[proxmoxにvirtualboxのマシンをインポートする](https://zarat.hatenablog.com/entry/2020/06/26/195540)
SwiftUIで、カラーを選択できるViewを作る方法

このコードでは、テーマカラーを選ぶための画面が作られているんだよ。テーマカラーってのは、アプリやウェブサイトの見た目や雰囲気を決めるカラーのことなんだ。そのテーマカラーを選ぶためのビューが、このThemeColorSelectionViewっていうものなんだ。

このビューでは、ユーザーが選んだカラーを覚えておくための変数があって、それがselectedColorって名前なんだ。それには最初に.blueっていう青いカラーが入っているよ。

さらに、選べるカラーがいくつかあって、それがthemeColorsっていう配列で保持されているんだ。.blueや.redや.greenなどのカラーが入っているよ。

このビューでは、まず"Theme Color"って書かれたテキストが表示されているんだよ。

そして、その下にはボタンが横並びに表示されているんだ。この部分では、themeColorsの中のカラーの数だけ繰り返し処理が行われているんだよ。それぞれのカラーに対して、ボタンが表示されるんだ。ユーザーがボタンをタップすると、選んだカラーがselectedColorに設定されるよ。ボタンには選んだカラーで塗りつぶされた円が表示されているよ。選んだカラーと同じなら、白い縁がついているよ。

さらに、"Selected Color:"って書かれたテキストが表示されているんだ。その下には選んだカラーを示す円が表示されているんだ。円の中は選んだカラーで塗りつぶされていて、白い縁がついているんだ。

最後に、ビューの周りにはpaddingが追加されていて、余白が設定されているんだ。

ContentViewでは、このテーマカラー選択ビューが表示されているんだよ。ContentViewはアプリやウェブサイトのメインの画面で、ここから始まるんだ。

ContentView_Previewsでは、このビューのプレビューが提供されているんだ。プレビューでは、ビューの見た目や動きを確認することができるよ。
```Swift

struct ThemeColorSelectionView: View {
    // ユーザーが選択したカラーを管理する状態変数
    @State private var selectedColor: Color = .blue
    
    // 使用可能なテーマカラーの配列
    let themeColors: [Color] = [.blue, .red, .green, .orange, .purple]
    
    var body: some View {
        VStack(spacing: 20) {
            // テキストを表示
            Text("Theme Color")
                .font(.headline)
            
            HStack(spacing: 10) {
                // 使用可能なテーマカラーの数だけループ
                ForEach(themeColors, id: \.self) { color in
                    // ボタンを作成し、タップされた時に選択されたカラーを更新する
                    Button(action: {
                        selectedColor = color
                    }) {
                        // 円形のビューを表示し、選択されたカラーで塗りつぶす
                        Circle()
                            .fill(color)
                            .frame(width: 50, height: 50)
                            .overlay(
                                // 選択されたカラーと一致する場合は白い縁を表示し、それ以外は縁を表示しない
                                Circle()
                                    .stroke(Color.white, lineWidth: selectedColor == color ? 4 : 0)
                            )
                    }
                }
            }
            
            // 選択されたカラーを表示するテキストを表示
            Text("Selected Color:")
            
            // 選択されたカラーを示す円形のビューを表示
            Circle()
                .fill(selectedColor)
                .frame(width: 100, height: 100)
                .overlay(
                    // 白い縁を表示
                    Circle()
                        .stroke(Color.white, lineWidth: 4)
                )
        }
        .padding()
    }
}

struct ContentView: View {
    var body: some View {
        // テーマカラー選択ビューを表示
        ThemeColorSelectionView()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        // コンテンツビューをプレビュー表示
        ContentView()
    }
}
```


作ったアプリ。


https://apps.apple.com/app/6446189340


では。
【AWS】大量のLambda関数の一括バックアップと復元ガイド

前任者が作成した大量の不要なLambda関数(約50個)を整理しているのですが、そのまま削除するのも怖いので、一応バックアップをとることにしました。

Lambda関数のバックアップや復元は、SAM(Serverless Application Model)やCloudFormationを使用するのが一般的らしいのですが、個別のテンプレートをつくるのが面倒だったので、AWS CLIで関数のコードと設定を一括で扱う方法を試してみました。

# バックアップ
`lambda_functions.txt` というファイルに全てのLambda関数名をリストアップします。

```bash
aws lambda list-functions --query 'Functions[*].[FunctionName]' --output text > lambda_functions.txt
```

次に、シェルスクリプト`backup_lambda.sh`を作成して各Lambda関数の設定とコードをダウンロードします。

```shell: backup_lambda.sh
while read function; do
  echo "Backing up $function"
  aws lambda get-function --function-name $function --query 'Configuration' > $function-config.json
  aws lambda get-function --function-name $function --query 'Code.Location' --output text | xargs wget -O $function.zip
done <lambda_functions.txt
```

このスクリプトは `lambda_functions.txt`にリストアップされた各Lambda関数に対して以下の処理を行います。

- 関数の設定をJSON形式でダウンロードし、関数名をつけたJSONファイル(`$function-config.json`)に保存
- 関数のデプロイメントパッケージ(実行に必要なコードと依存関係のライブラリをまとめたもの)をダウンロードし、関数名をつけたZIPファイル(`$function.zip`)に保存

これで一度にすべてのLambda関数のバックアップを取ることができます。

※バックアップの保存先は用途によって適宜選択します。復元時にすぐにオブジェクトへアクセスできるように、私はS3 Glacier Instant Retrievalを選びました。SSEは有効化しましたが、バージョニングやアクセスログは有効化していません(データの重要度やリスクの許容度を考慮した上で)。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/9b47efde-321a-7514-1363-b9d76694be29.png" width="500">

# 復元
保存したコード(ZIP)と設定ファイル(JSON)を使用して、各関数を手動、もしくは自動で復元します。

## 個別関数の手動復元
1. AWS Lambdaコンソールにログイン
2. "関数の作成"をクリック
3. "一から作成"を選択
4. バックアップした設定ファイル(**`~.json`**)を参照して、関数名、ランタイム、ロールなどの設定を入力
5. 関数の作成をクリック
6. 新たに作成した関数のページに移動し、"関数コード"セクションで"アクション"->"ZIPファイルをアップロード"を選択し、バックアップしたZIPファイル(**`~.zip`**)をアップロード

## シェルスクリプトによる複数関数の自動復元
複数のLambda関数を自動で復元したい場合にはシェルスクリプトをつかいます。

まずは、復元したいLambda関数の名前リスト(.txt)をつくります。

```txt
lambda-aaa
lambda-bbb
lambda-ccc
```
シェルスクリプト`restore_lambda.sh`を作成します。
    
```shell: restore_lambda.sh
while read function; do
    echo "Restoring $function"
    role=$(jq -r '.Role' $function-config.json)
    handler=$(jq -r '.Handler' $function-config.json)
    runtime=$(jq -r '.Runtime' $function-config.json)
    aws lambda create-function --function-name $function --handler $handler --runtime $runtime --role $role --zip-file fileb://$function.zip
done <lambda_functions.txt
```
    
シェルスクリプトに実行権限を付与します。
    
```bash
chmod +x restore_lambda.sh
```
    
シェルスクリプトを実行します。

```
./restore_lambda.sh
```
【LangChain】リクエスト前にトークン数を確認するには

トークン数が上限に到達すると困ったことになります。
リクエストを行う前にメッセージリストのトークン数を確認したい時、ありますよね。
それも、お金をかけずに。

[忙しい人向け: 結論へジャンプ](#リクエスト前にメッセージリストのトークン数を確認するには)

# トークン数には上限がある
:::note warn
しかも、**往復の合計トークン数を上限以下にしなければならない**。
:::
リクエスト時のトークン数は、AIの回答(レスポンス)のトークン数も考慮しておく必要があります。

例えば、`gpt-3.5-turbo`の上限は`4096トークン`です。
回答で`600トークン`程度消費するならば、リクエスト時のトークン数は`3500トークン`程度になるようした方が良いでしょう。

>API Reference - OpenAI API
https://platform.openai.com/docs/models/gpt-3-5
https://platform.openai.com/docs/api-reference/chat

## リクエスト時にトークン数を消費しすぎると？
レスポンス用にトークン数を残しておかないと、レスポンス時にAIの回答が期待通りになりません。
途切れたり、空になります。

## トークン数上限を超えてリクエストすると、例外が発生する
そもそも上限近くのリクエストをしたところで、期待通りの回答は得られませんが、一応紹介しておきます。

トークン数上限を超えたメッセージリストをリクエストすると、例外が発生します。

例えば、以下のようなコードでトークン数上限を超えた`8814トークン`でリクエストしようとすると、例外が発生します。~~やばいよ。~~

:::note warn
以下のコードは、`.env`ファイルに`OPENAI_API_KEY="OpenAI APIキー"`を設定している前提です。
:::
```python
import dotenv
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage,
)
from langchain.chat_models import ChatOpenAI
dotenv.load_dotenv()
messages = [
    [
        SystemMessage(content="振る舞いなどを記述したプロンプト"),
        HumanMessage(content="スーパー長い文章"),
        AIMessage(content="それっぽいAIの回答のキッカケとか"),
    ],
]
chat = ChatOpenAI()
response = chat.generate(messages)
```
```
This model's maximum context length is 4097 tokens. However, your messages resulted in 8814 tokens. Please reduce the length of the messages.
```

# リクエスト前にメッセージリストのトークン数を確認するには
:::note info
`get_num_tokens_from_messages()メソッド`で確認できた
:::
ふとライブラリの実装を見に行くと、`ChatOpenAIクラス`の中に使えそうなメソッドがありました。

それが`get_num_tokens_from_messages()メソッド`です。

このメソッドでは、トークン数を内部的に算出しているので、API利用料はかかりません。

例えば、先述のコードに、送信予定のトークン数で処理を分岐するような実装を追加するならば、以下のようになります。
```python
import dotenv
from langchain.schema import (
    AIMessage,
    HumanMessage,
    SystemMessage,
)
from langchain.chat_models import ChatOpenAI
dotenv.load_dotenv()
messages = [
    [
        SystemMessage(content="振る舞いなどを記述したプロンプト"),
        HumanMessage(content="スーパー長い文章"),
        AIMessage(content="それっぽいAIの回答のキッカケとか"),
    ],
]
chat = ChatOpenAI()
token_size = chat.get_num_tokens_from_messages(messages=messages[0])
token_limit = 4096 - 800    # 復路のトークン数を確保するため減算
if token_size <= token_limit:
    response = chat.generate(messages)
else:
    print(f"トークン数が多すぎます。トークン数: {token_size}")
```
```
トークン数が多すぎます。トークン数: 8814
```

`get_num_tokens_from_messages()メソッド`は、ライブラリ内部で呼び出されるメソッドとして用意されているようです。
このメソッドをライブラリ外から呼び出すことについて、それが推奨されている行為か否かは確認していません。
使用する場合は自己責任で。
> hwchase17/langchain/langchain/chat_models/openai.py - GitHub
https://github.com/hwchase17/langchain/blob/master/langchain/chat_models/openai.py

# あとがき
自前でtiktokenを用いたトークンカウンタなどを作ったりしていましたが、算出されるトークン数が実際のトークン数と中々合わずに苦戦していました。
これで要約系の実装が捗るぜ。

# 参考
> hwchase17 / langchain
https://github.com/hwchase17/langchain

> LangChain Docs
https://python.langchain.com/en/latest/index.html
GPT文章校正アシスタントを作りました(日本語・英語対応)

# GPT文章校正アシスタントを作りました(日本語・英語対応)
こんにちは、皆さん。今日は私が開発した新しいツール、GPT文章校正アシスタントについて紹介したいと思います。

## はじめに
私たちは日々、さまざまな文書を書いています。仕事の報告書、ブログ記事、メールなど、その内容はさまざまです。しかし、どのような文書であれ、その品質は文法やスペルの正確さに大きく影響されます。

この問題を解決するために、私はOpenAIのGPT-3.5-turboまたはGPT-4モデルを使用した文章校正アシスタントを開発しました。このツールは日本語と英語の文書を校正することができます。

## ツールの特徴
-   日本語と英語の文法や誤字脱字を自動的に修正します。

-   入力されたテキストの言語を自動的に判定します。

-   校正結果を元のテキストと比較して表示します

-   ユーザーが毎回校正のプロンプトを書く手間を省きます。

## ツールの概要
このツールはOpenAIのAPIを利用して、日本語と英語の文書を校正します。ユーザーは校正したいテキストを入力すると、ツールはそのテキストを校正し、校正後のテキストと修正箇所を表示します。

プロジェクトのメインの流れは以下です。

``` mermaid
graph TB
A[ユーザーが文書を入力] --> B[言語を検出]
B -->|日本語| C[日本語のプロンプトを選択]
B -->|英語| D[英語のプロンプトを選択]
C --> E[OpenAI APIによる校正]
D --> E
E --> F[校正後のテキストを表示]
E --> G[原文と校正後のテキストの差分を計算]
G --> H[差分を表示]
```
また、このツールはWebアプリとして構築されており、誰でもブラウザからアクセスして使用することができます。

## 使い方
[このリンク](https://dayuanjiang-gpt-grammar-checker-app-7exi89.streamlit.app/?utm_medium=oembed)から直接アクセスすることができます。

スクリーンショット：
![](https://github.com/DayuanJiang/gpt_grammar_checker/raw/main/images/paste-1.png)


## まとめ
GPT文章校正アシスタントは、日本語と英語の文書を校正する強力なツールです。OpenAIのGPTモデルの力を借りて、文書の品質を向上させることが可能です。

このツールが皆さんのライティング作業を助けることができれば幸いです。是非一度お試しください。

それでは、Happy Writing!

注：本文はGPT生成した上で編集したものです。
python-pptxによる代替テキストへのアクセス

## 代替テキスト機能とは

Microsoft Officeソフトウェアにおいて、各種オブジェクトに説明をつけるための機能です。
資料の読み上げ時に画像を説明するために利用されるそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841874/c646fcd6-6722-e656-46c6-b5a38c96c3eb.png)

## python-pptxで代替テキストにアクセスするには
最新版のpython-pptxでは代替テキストへのアクセス機能が実装されていません。
最新版は2021年9月にリリースされたもので、今後のアップデートも期待薄でしょう。

ただしインストール済みのpython-pptxを改変することで実装出来ます。
具体的な方法は下記のURLに則り、setterも実装しました。
https://github.com/scanny/python-pptx/pull/512/files


まずはpython-pptxのインストール先を調べましょう。
```python
import pptx
print(pptx.__file__)    # C:\Users\..(中略)..\pptx\__init__.py
```

表示された\_\_init\_\_.pyが存在するpptxフォルダを開き、
oxml/shapes/shared.pyに下記の記述を追加します。

```diff_Python:oxml/shapes/shared.py (170行目付近)
    @property
    def txBody(self):
        """
        Child ``<p:txBody>`` element, None if not present
        """
        return self.find(qn("p:txBody"))

+   @property
+   def shape_alt_text(self):
+       return self._nvXxPr.cNvPr.descr
+
+   @shape_alt_text.setter
+   def shape_alt_text(self, new_alt_text):
+       self._nvXxPr.cNvPr.descr = str(new_alt_text)

    @property
    def x(self):
        return self._get_xfrm_attr("x")
```


```diff_Python:oxml/shapes/shared.py (315行目付近)
    name = RequiredAttribute("name", XsdString)
+   descr = OptionalAttribute('descr', XsdString)
    del _tag_seq
```


つづいてpptxフォルダに戻り、shapes/base.pyに下の記述を追加します。
```diff_Python:shapes/base.py (135行目付近)
    @name.setter
    def name(self, value):
        self._element._nvXxPr.cNvPr.name = value

+   @property
+   def alt_text(self):
+       return self._element.shape_alt_text
+
+   @alt_text.setter
+   def alt_text(self, new_alt_text):
+       self._element.shape_alt_text = new_alt_text

    @property
    def part(self):
```

これで準備は完了です。

## 動作確認例
最初のスライドに画像（図形でも可）を1つ貼り付け、適当に代替テキストを設定してSample.pptxという名前で保存しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841874/89947a04-33c6-8b12-c459-61f59debd2cf.png)

この代替テキストを表示した上で、変更して別ファイルとして保存するサンプルです。
```Python
from pptx import  Presentation

prs = Presentation('./Sample.pptx')
print(prs.slides[0].shapes[0].alt_text)    # '悩めるアザラシ'
prs.slides[0].shapes[0].alt_text = '実は眠いだけ'
prs.save('Modified.pptx')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2841874/4b3ddf86-9ec3-06d9-8eae-a8c82d05fb7f.png)

問題なく表示・変更できることが確認されました。
IoT学習環境の整備

### IoT学習環境の整備について
IoTは分野が広く、幅広い知識が必要になる。
本記事では、入門に必要な機材をある程度を揃えば、安い費用で学習することが可能です。
なお、キーボード、マウス、ディスプレイがすでにある前提としています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/4a63d701-dd6a-cd67-c2da-a84f0a98136c.png)

### RaspberryPi
現在のアマゾンの相場だと本体価格がRaspberryPi4で2万円～2万5千円
電源、HDMIケーブルが必須、RaspberryPi4は発熱するため、ヒートシンクとファンが必須
SDカードは16GB以上だが、筆者は32GBを使用
なお、RaspberryPi4からUSB起動ができるようになるため、USBフラッシュメモリで代用が可能 

### 周辺機器
- 各種センサー、セット（ブレッドボード、抵抗、LED、サーボモーター、DCモーターが含まれている場合もある）で売っているものは、4000円前後
- RaspberryPiマガジンを1冊買っておく
- RaspberryPiカメラモジュール（あるとやれることの幅が広がる）
- ロボットアーム（こちらもあるといろいろ試せます）

### 機械学習を試す場合
機械学習をさせる場合は、別途高性能なPCを用意する必要がある
学習結果をpickleファイルに保存して、IoT機器でテストするという使い分け

### 3Dプリンタ
構想したアイディアを物理的に実現するハードウェアとの組み合わせを考える場合は必須
この場合はCADで図面を書き、筐体、部品などを３Dプリンタで製作する。
３Dプリンタの相場は2万円前後で組み立てが必要でないものがお勧めしますが、
組み立てに自信が持っている人は1万円台で入手が可能

### IoTの学習概要
以下の学習マップを参考に組み立てる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/576081/f73a0951-abce-e751-0c80-64153b2f2dad.png)
HTML&CSS Day3:CSSの基本

# １.概要
参考書のChapter４にてcssの基本的な使い方を学習。
サイトのヘッダーとフッターのレイアウトを調整した。

# 2.目次
- CSSを記述する場所
- CSSの基本的な書き方
- 使用したプロパティ
- ウェブフォント
- 感想

# 3.CSSを記述する場所
記述する場所は3つのパターンがある。

**●タグのstyle属性に直接記述する**
HTMLの中の要素に対して直接スタイルを指定。
```css:
    <p style="color : red;">この文字の色を赤くする</p>
```

**●style要素内に記述する**
head要素内にstyle要素を作成し、その中にCSSを記述。手軽に利用できる。
ページ数の多いサイトでは管理しづらい欠点があり。
```css:
    <style>
    p {
        color: red;
    }
    </style>
```

**●外部ファイルに記述する**
CSSファイルを別に用意し、link要素でHTMLファイルから参照させる。
現場ではこの方法が多い（らしい）。
・文書構造はHTML、装飾はCSSと切り分けることにより、ウェブブラウザや検索エンジンに効率よく正確な情報を伝えることができる。
・1つのCSSぶんしょを複数のHTMLファイルへリンクさせることができるため、１箇所を編集するだけで関連づけられたすべたてのHTMLファイルへ変更が反映され、ページ修正や管理が楽になる。

▼HTMLファイルの記述
```html:
    <link href="./style.css" rel="stylesheet">
```


▼CSSファイル(style.css)の記述
```css:   
p {
    color: red;
}
```

:::note info
スタイルが競合した時の優先順に注意
コードが間違っていなくて、正しく装飾されない場合は、
優先順が競合しているかもしれない
:::

# 4.CSSの基本的な書き方

### (1)スタイルシートの基本文法
セレクタ {プロパティ:値;}

セレクタ ： 適用する対象（どれの）
プロパティ　：　スタイルの種類（何を）
値　：　適用させたい結果（どうするか）

プロパティと値の間にコロン(:)を記述することでセットとなる。
このセットのことをスタイル宣言と言う。
セミコロン(;)は1つのセレクタに複数のスタイルを指定する際に
それぞれのスタイル宣言を区切るための記号。

今回は主に1つのセレクタに複数のスタイルを指定。
ほかに
　・複数のセレクタに同じスタイルを指定
　・特定の場所にあるセレクタだけに別の指定をする
ことも可能。その場合は、参考書のp.96〜97を参照。

# 5.CSS設計ポイント
### (1).ブラウザの既定スタイルを解除
各ブラウザにはデフォルトのスタイルがそれぞれ独自に設定されている。
ブラウザによって見た目が変わったり、不要な余白ができたりと意図しない表示とならないよう、デフォルトのスタイルを最初に解除する。

■要素の幅と高さの計算方法（CSSボックスモデル）を指定
計算方法の指定はbox-sizing プロパティを使用。
初期値は「content-box」
 :要素の大きさを「width＋heightの値」＋paddingの値」＋「borderの太さ」で計算
　→レスポンシブデザインなどで幅や高さを「％」のような可変する単位で指定すると、計算が複雑になる。

これを解決するため、「border-box」を指定。
　：要素の大きさは「width＋heightで指定した値のみ」

↓は要素の余白もなくしている
```css:   
::before,
::after {
    padding: 0;
    margin: 0;
    box-sizing: border-box;
}
```

■他、リストの行頭アイコンを非表示、リンクの文字色と下線をなくす
```css:  
ul,
ol {
  list-style: none;
}

a {
  color: inherit;
  text-decoration: none;
}
```

### (2).ベースになるスタイルを指定
■ページ全体のスタイルを設定
```css:   
body {
  font-family: sans-serif;
  font-size: 16px;
  color: #000000;
  line-height: 1;
  background-color: #ffffff;
}
```

■img要素の最大幅を指定
```css:   
img {
  max-width: 100%;
}
```

### (3).レイアウトの詳細を記述する
参考書のp.112〜124を参考に、レイアウトの詳細を記述。

# 6.ウェブフォント
Google Fontsを使用。
フォントを検索
↓
使用するスタイルを検索
↓
埋め込みコードを表示する
↓
HTMLコードをコピーして貼り付ける
↓
CSSコードをコピーして貼り付ける

# 7.感想
コードを書いて保存するたびに、表示が変わるのが楽しい！
今回は幅とかの値は参考書に記載の通りにしたけど、全体を見ながら今後は調整をしていくんだろうな。
nix-shellで開発環境を準備する

## 対象読者
- Pythonでプロジェクトを管理している人
- poetryユーザー
- nix-shellユーザー

## nix-shellとは
nix package managerを利用して開発環境を準備するためのソフトウェア [参考](https://blog.tomoyukim.net/entry/nix-shell-nodejs/)

## 使い方
プロジェクト直下のshell.nixファイルに次のように記載する
```nix
let pkgs = import <nixpkgs> {};

in pkgs.mkShell rec {
  name = "two-stage-distant-ner";

  buildInputs = with pkgs; [
    python39
    python39Packages.poetry
  ];

  shellHook = ''
  poetry config virtualenvs.in-project true
  poetry install
'';
}
```

その後、シェル上で次のコマンドを打つとプロジェクト直下に仮想環境がインストールされる
```sh
nix-shell
```

## 結論
便利！！！Nixバンザイ！！
google clone Part15　30 Create Search result component 3/3 APIのレスポンスのHTMLを反映するために　react-parserを導入

# 概要

目次

https://qiita.com/RYA234/items/7cf917e4e5cdea668e2e

今回はReact-parserを使って、Responseの文字列をHTML文として表示するよう実装します。
以下画像は実装後の様子です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/2ea5de5a-c9f2-de8d-b173-65570e82e120.png)



# 開発環境

OS:Windows10
IDE:VSCode

"@next/font": "13.1.5",
"autoprefixer": "10.4.14",
"eslint": "8.39.0",
"eslint-config-next": "13.3.1",
"next": "13.3.1",
"postcss": "8.4.23",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-icons": "^4.8.0",
"tailwindcss": "3.3.2"

# 実装のポイント
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710623/56fa8c87-9333-6ed1-cd8a-ff750e5decad.png)

# コード部分
## package
```diff_json:package.json
{
  "name": "googlecone12",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "autoprefixer": "10.4.14",
    "eslint": "8.39.0",
    "eslint-config-next": "13.3.2",
    "next": "13.3.2",
    "postcss": "8.4.23",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "tailwindcss": "3.3.2",
    "react-icons": "^4.7.1",
+    "html-react-parser": "^3.0.9"

  }
}
```

## WebSearchResults
```diff_jsx:WebSearchResults.jsx
import Link from "next/link";
import Parser from "html-react-parser";

export default function WebSearchResults({results}){
   return(
    <div className="w-full mx-auto px-3 pb-24 sm:pl-[5%] md:pl-[14%] lg:pl-52">
        <p className="text-gray-600 text-sm mb-5 mt-3">
            About {results.searchInformation?.formattedTotalResults}
            results ({results.searchInformation?.formattedSearchTime} seconds)
        </p>  
        {results.items?.map((result) => (
            <div className="mb-8 max-w-xl" key={result.link}>
                <div className="group flex flex-col">
                    <Link className="text-sm truncate" href={result.link}>
                        {result.formattedUrl}
                    </Link>
                    <Link className="group-hover:underline decoration-blue-800 text-xl truncate font-medium text-blue-900" href={result.link}>
                        {result.title}
                    </Link>
                    <p className="text-gray-600">
+                        {Parser(result.htmlSnippet)}
                    </p>
                </div>
            </div>
        ))}
    </div>
   ) 
}
```




# 参考



## その他
react-parser

https://www.npmjs.com/package/html-react-parser

https://github.com/remarkablemark/html-react-parser

Udemy

githubコミット分

https://github.com/RYA234/googlecone12/commit/b94a3e2302ef0e8c091b4a20d34822fb372fc4de