OmniAICreator/Qiita-1.07M huggingface dataset:
AQM0802AをソフトウェアI2C(SoftWire.h)で遊ぶ(Arduino UNO)


目的
ソフトウェアI2Cで遊ぶ。


結果

![o_coq076.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/0691e4c4-38ae-b898-f197-f9251ed3ce0f.jpeg)


![o_coq077.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/6008608c-31b6-2bbd-7714-4c9ef6a7ad1c.jpeg)

![o_coq078.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7516b23a-27a5-0e04-3745-fa3b097bedb4.jpeg)


プログラム


```c++



//Soft_I2C_AQM0802A_DEMO1_UNO


#include <SoftWire.h>
#include <AsyncDelay.h>

#if defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)
int sdaPin = PIN_WIRE_SDA;
int sclPin = PIN_WIRE_SCL;

#else
int sdaPin = SDA;
int sclPin = SCL;
#endif

SoftWire sw(sdaPin, sclPin);

// I2C address of AQM0802A
const uint8_t I2C_ADDRESS = 0x3E;

//i2cバッファー
char data_read[4];

//初期レジスター
char INIT_com[] = {
  0x0, 0x38, //1
  0x0, 0x39, //2
  0x0, 0x4,  //3
  0x0, 0x14, //4
  0x0, 0x70, //5
  0x0, 0x56, //6
  0x0, 0x6C, //7
  0x0, 0x38, //8
  0x0, 0xC   //9
};

//画面のクリアレジスター
char INIT_cls[] = {0x0, 0x1};


//i2c書き込みルーチン
void i2c_lcd_w(char *buff1) {

  // Ensure register address is valid
  sw.beginTransmission(I2C_ADDRESS);
  sw.write((uint8_t)buff1[0] ); // Access the first register
  sw.write((uint8_t)buff1[1] ); // Access the first register
  sw.endTransmission();
  delay(2);
  
}//i2c_lcd_w


void ns_putc(char ch)
{

  data_read[0] = '@';
  data_read[1] = ch;

  //I2Cに送信
  i2c_lcd_w(data_read);

}//ns_putc


void ns_puts(const char *str1)
{

  //文字の中身がゼロか
  while (*str1) {

    //一文字出力
    ns_putc(*str1 ++);

  }//while

}//ns_puts


//カーソルの移動
void setCursor(int col, int rows)
{

  data_read[0] = 0x0;
  data_read[1] = 0x80 +  (rows * 0x40) + col ; //カーソルを移動

  //I2Cに送信
  i2c_lcd_w(data_read);

}//setCursor


char swTxBuffer[16];
char swRxBuffer[16];

//初期化関数
void setup()
{

  //I2Cの初期化
  Serial.begin(115200);
  Serial.print("    SDA pin: ");
  Serial.println(int(sdaPin));
  Serial.print("    SCL pin: ");
  Serial.println(int(sclPin));
  Serial.print("    I2C address: ");
  Serial.println(int(I2C_ADDRESS), HEX);
  sw.setTxBuffer(swTxBuffer, sizeof(swTxBuffer));
  sw.setRxBuffer(swRxBuffer, sizeof(swRxBuffer));
  sw.setDelay_us(5);
  sw.setTimeout(1000);
  sw.begin();

  //液晶の初期化
  for (int ii = 0; ii < 9; ii++) {
    i2c_lcd_w(&INIT_com[ii << 1]);  // ii << 1 = ii * 2
  }//for

  //画面のクリア
  i2c_lcd_w(INIT_cls);

  //表示
  setCursor(0, 0); ns_puts("HELLO");
  setCursor(0, 1); ns_puts("WORLD");

}//setup


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



```
AWSとGit


## はじめに

この記事はAWS SAA試験勉強のための、AWSとGitを連携に関する知識のまとめです。



## AWS CodeCommit
AWSのマネージドGitリポジトリサービスであるCodeCommitを使用すると、AWSリソースとの連携が簡単になる。
CodeCommitを使用すると、AWSの認証情報を使用してリポジトリにアクセスできる。

## AWS CodePipeline
CodePipelineは、AWSのCI/CDサービスであり、異なるソースコードリポジトリ（たとえば、GitHubやCodeCommitなど）からソースコードを取得し、ビルド、テスト、デプロイなどのアクションを実行できる。



## AWS Lambdaと組み合わせ
Lambda関数を使用して、特定のGitリポジトリの変更をトリガーにして自動化された処理を実行することができる。
GitHub WebhookやAWS CodeCommitのトリガーとしてLambda関数を設定することができる。

## AWS CloudFormation
CloudFormationを使用して、インフラストラクチャのコード化を行い、Gitリポジトリにコードとして保存することができる。
インフラストラクチャの変更は、CloudFormationテンプレートの変更としてGitにコミットされる。

## EC2上にGitLabサーバーを構築する

EC2で運用しているGitLabのリポジトリのバックアップを作成する最もシンプルな方法は、EC2にアタッチされているリポジトリを保存しているEBSボリュームのスナップショットを、Data Lifecycle Managerで毎日作成する方法。
面接で聞かれるプログラミングに関する質問とその回答

## はじめに
この記事では、エンジニアが面接で聞かれる技術的な質問と、それらに対する回答を紹介します。

## 1. 継承とは何か？継承の欠点は？
継承はオブジェクト指向プログラミングにおいて、あるクラスが別のクラスの属性やメソッドを引き継ぐことを可能にする概念です。コードの再利用を促進し、プログラムの構造をクリアにすることができます。

**欠点**:
- **密結合**: 基底クラスの変更が派生クラスに影響を与え、プログラムの保守が困難になる。
- **理解の難しさ**: 多重継承はプログラムの流れを追いづらくする。
- **過剰な一般化**: 不必要な機能を持つクラスが生成されることがある。

## 2. プログラムはクラスだけで書いた方が良い？意見を述べてください。
クラスのみでプログラムを書くことは、オブジェクト指向言語では一般的ですが、すべての場合に最適とは限りません。関数型プログラミングなど他のパラダイムが特定の問題に対してより適切な解決策を提供する場合もあります。

## 3. DRYやSOLIDの原則について説明してください。
- **DRY ("Don't Repeat Yourself")**: コードの重複を避けることで、バグの発生を減らし、メンテナンスを容易にします。
- **SOLID**: オブジェクト指向設計の五つの基本原則です。
  - **Single Responsibility Principle**: クラスは一つの責任のみ持つべき。
  - **Open/Closed Principle**: クラスは拡張には開かれ、変更には閉じるべき。
  - **Liskov Substitution Principle**: 派生クラスはその基底クラスと置換可能でなければならない。
  - **Interface Segregation Principle**: 大きなインターフェイスよりも小さな専用のインターフェイスが望ましい。
  - **Dependency Inversion Principle**: 依存関係は具象ではなく抽象に対して持つべき。

## 4. HTTPステータスコードってどのような時に何を返す？200番台は？400番台は？500番台は?
HTTPステータスコードは、サーバーがクライアントのリクエストに対して応答する際の状態を示します。
- **200番台（成功）**: クライアントのリクエストが正常に処理されたことを示します。最も一般的なのは200 OKです。
- **400番台（クライアントエラー）**: クライアントのリクエストに問題があることを示します。404 Not Foundや400 Bad Requestなどがあります。
- **500番台（サーバーエラー）**: サーバー側で問題が発生したことを示します。500 Internal Server Errorが代表的です。

## 5. HTTPリクエストが送られる時に中で起きてる事を教えて
HTTPリクエストが送られるとき、以下のステップが実行されます：

1. **DNS解決**: クライアントはサーバーのドメイン名をIPアドレスに解決する必要があります。
2. **TCP接続**: サーバーのIPアドレスとポート番号を用いてTCP接続が確立されます。
3. **HTTPリクエスト送信**: クライアントはHTTPプロトコルに従ってリクエスト（例えばGET、POST）をサーバーに送信します。
4. **サーバー処理**: サーバーはリクエストを解析し、適切なレスポンスを生成します。
5. **HTTPレスポンス送信**: サーバーはHTTPステータスコードとともにレスポンスをクライアントに送り返します。
6. **TCP接続終了**: レスポンス後、TCP接続は通常終了されます。
unity recorderで録画できなくなって悩んだ話

UnityにはUnity Recorderという、エディタ上でプレイしているゲームの画面を録画して、ムービーにしたり、それとも連番の画像にしたり出来る、大変に便利なソフトがpackage mangerからインストール出来る。
ワタクシ、これをとても便利に使っていたのだけど、ある日、突然mp4が作れないと、Recorder君が文句をブー垂れてくるようになった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96586/082e2538-ff1b-e287-5749-4d8e2f3dc887.png)

 Movieに **"!"の赤マーク** が出て、録画させてくれない。
 さっぱり理由が分からず、パッケージの再インストールしてみたり、イロイロ試したのだけど、復帰しないので、仕方なく、最近、動画も撮影できるようになったマイクロソフトご謹製のスニッピングツールを使って録画していた。
だが、ゲーム画面を録画したいのに撮影できないのはマジ困るので、しばらく理由を調べていたところ、信じられないほど簡単な原因だった。

:::note alert
**Unity Recorder は縦横のどちらかの解像度が奇数になった画面では録画は出来ない**
:::

全く当たり前の話なのだけど、どうして気がつかなかったのか？
その理由は最初に出したスクショにある。なんも考えずにunity recorderを出すとスクショぐらいのウインドウとして出るのだけど、それだと**エラーメッセージが表示されない**のだ。
ウィンドウを大きくすると…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96586/3a1f794b-02f7-bee4-5508-43a9940cb5ea.png)

なんと、一番下にエラーメッセージが出ているのである。
気がついたときは **「あれ？　インターフェースのスクロールバーの下が妙に空いてるぞ？」** と思って、ウィンドウを広げたら、このエラーが出てきたという顛末。
なんてこったい。

ところでどうしてこんなことになったのか？
まず、僕はGame WindowをFree Aspectにしていた。
理由は簡単でイロイロないただけないスマホの縦横比でも正しくUIが動作するかの確認をするとき、適当にサイズをいじる方が手っ取り早かったからだ。適当にいじって変なサイズにしてUIが正しく整列していれば、アンカー周りにバグがないことがわかる。
そして**運悪くGame Windowの縦か横のレンダリングサイズが奇数になると、このエラーが発生する**わけである。
この問題を回避するには－－

- RecorderのinputにMatch Window Sizeを使わない
- 縦横比のセットをたくさん用意する
- いじって確認したら、最も使うアスペクト比に戻す

といったところだと思うが、わかってしまえば、どってことのないエラーなので、ま、こんな笑っちゃうエラーで何日も悩まされることもあるってぐらいのエピソードにしておきたい。

ところで、これを思わずtwitter(X)に書いたとき、元unityの小林さん曰く。

https://twitter.com/nyaa_toraneko/status/1785326970706055188

あー、この機能はそういうことのために用意されていたんですね、と理解したのであった。
Linuxにおける生成AI活用法

:::note alert
生成AI利用にあたって、ご自身の所属する組織のポリシーを順守の上、ご活用願います。
:::
# はじめに
AIの進化は目覚ましく、その波はLinuxの世界にも押し寄せています。ITエンジニアにとって、生成AIは単なるツールではなく、生産性を飛躍的に向上させるパートナーとなり得ます。この記事では、Linuxを利用するにあたって私自身がどうやって生成AIを活用しているのかいくつかご紹介します。 

:::note info
今回利用するのはMicrosoft Copilotです。
:::

# 活用法①ログ解析
Linuxを利用する中で、ログを見ることはよくあると思いますが、複雑な事象に遭遇すると、「ログの前後関係や別プロセスのログを見ないと、エラーを起こしている原因がわからない」なんてことがよくありますよね。
そこで私が活用しているのが、エラーを起こしていそうなプロセスに関するログを全て生成AIに入力し、前後関係の読み解きをしてもらって、原因になっていそうな設定を推測してもらうというものです。一見、見当違いな推測をしそうですが、かなり精度の良い推測をしてくれます。

# 活用法②一次情報の調査
Linuxを設定する際に個人BLOGを参考にすることが多くあると思うのですが、そのパラメータが正しいかの”根拠”が欲しい時、めちゃくちゃありますよね。根拠というと、公式のリファレンスマニュアルを元にすることが多いと思うのですが、自分が欲しい情報って中々見つからないですよね。そこで生成AIにパラメータと意味を聞くと、回答が出力されれ、必ず参照元を提示してくれるので、その中で公式のものを探していくという活用方法をしています。この方法を取ると調査にかかる時間をかなり削減できます。

# 活用法③スクリプト解読、出力
私自身、スクリプトを書くのがとても苦手でスクリプトを読むのも書くのも避けてきたのですが、生成AIが登場したことによって、だいぶハードルが下がったなと感じています。AIに入力すれば意味も教えてくれますし、実現したいこと・どんなプロセスを使ってというような情報を入力すれば、後は自分自身が細かいところを詰めればいいだけの状態で出力してくれるので大変重宝しています。

# さいごに
今後、生成AIはますます進化を遂げ、私たちエンジニアにとって非常に有益なパートナーとなっていくことかと思います。ただし、非常に便利である側面、ハルシネーションを起こし、不確かな情報を出力することも多いので、自分自身がその情報が正確かどうか見極められるように技術力・知見を高めていくことが重要です。

また、生成AIの活用は、私たちの問題解決能力を補完するものであり、それに依存することなく、自らの判断と責任を持って行動することが求められます。Linuxの世界では、オープンソースの精神に基づき、共有と協力を通じて成長してきました。生成AIもこの精神を受け継ぎ、コミュニティ全体の発展に寄与することができるでしょう。

最後に、生成AIを活用する上での倫理的な考慮も忘れてはなりません。データのプライバシー保護、知的財産権の尊重、そしてバイアスのない公平な技術の開発と使用が、私たち全員にとっての責任です。エンジニアとして、これらの原則を守りながら、生成AIの可能性を最大限に活かしていきましょう。
Windows Serverの機能紹介

# Windows Serverに関して

インフラ系の会社に入ったのにサーバー系を触ると思いきや、IT介護業務を行ってる、Masateruです。  

社会人として3年が経とうとしているのでいい加減エンジニア(笑)らしいアウトプットをしようと思い書いています。
おそらく現場に入ってでないと基本的にエンタープライズ製品に触らないであろうWindowsServerに関してです。  
初学者向けの説明になると思います。(間違っていたら、コメントいただけると幸いです。)

## そもそもWindowsServerって何？
### MS社(Microsoft Corporation)が作っているサーバー向けOSです。  
似たもので**Windows Storege Server**(現:Windows Server IoT for Storage)や**WindowsServer Datacenter**がありますが
~~DataCenterはあまり詳しくないので~~今回はWindowsServer Standardについてです。
        
### WindowsSeverはどんな運用(使い方)に向いている？
多種多様な使い方が出来ますが、個人的には**オンプレミス環境でのAD管理**(後ほど説明)で色々管理するのが向いているのであろうと感じます。


## WindowsSeverとクライアント向けWindowsOSとの違い
基本的には同じ機能で動いている為同じ操作感で動かせますが、明確に違う点が  
`Active Directoryの管理を行う事が出来る(ActiveDiectoryサーバーの構築が可能)`  
`PCへの最大接続数が制限なし`  
`WSUS(Windows Server Update Services)サーバーとしての利用が可能`  
と言った所でしょうか。

### 1.Active Directoryの管理を行う事が出来る(ActiveDiectoryサーバーの構築が可能)
私も、公式ドキュメント読んでも全然理解が追いつきませんが、  
簡単に言うとユーザー、組織単位で権限、設定の操作可能になる為に必要なシステムと思っていいただければ今回は大丈夫です。(本当はもっと深い。。。沼です。)  

### 2.PCへの最大接続人数制限がなし
よくあるお話だとファイル共有が20人までしか出来なくて誰かが接続切らないと別の人が共有出来ないとか、Apacheサーバー(WEBサーバー)を建ててWEBサイトにアクセス出来なくなってしまうとかでしょうか。  
WindowsServerだと上記のような制限がなくなり、最大接続人数が無制限になります。

### 3.WSUS(Windows Server Update Services)の利用が可能なる
言語化するとMSが準備しているWindowsUpdateサーバーのレプリカサーバーを作る事が出来る。という機能です。もちろんレプリカサーバのレプリカを作る事も可能です。

クライアント機側でWindowsUpdateの機能を利用して、やればいいじゃん！って思ってしまいますがもちろんメリットがあります。

WSUSサーバーを作成するメリットとしては  
`1.あらかじめレプリカサーバー上で不必要なKB(アップデートファイル)を弾く事が出来る`  
`2.ネットワークトラフィックの増加の抑制(帯域等の圧迫)`  
`3.(運用を頑張れば)非インターネット接続環境のイントラネット上でWindowsUpdateを行う事が可能`  

もちろんデメリットもあって  
`・定期的なメンテナンスをしてあげないとDB(データベース)が死ぬ`  
※基本はDBの再構築かWSUSの再インストールで直ります。

詳しくはIIJ様が詳しくまとめてるのでこちらを参考にすると良いかもしれません。  
https://ent.iij.ad.jp/articles/3061/

# Q.(上記全て)それLinuxで出来ないの？
### A.ほぼほぼ出来ます。
筆者はNAS利用で作った記憶がありますが、どうやらSamba自体に色々機能があるようです。  
(時間があればUbuntu等でADサーバー等立ててみたいですね)

日本sambaユーザー会
http://wiki.samba.gr.jp  
samba.org
https://www.samba.org/

## 最後に
Windowsは触っていてもWindows Serverなど触ってこなかったのでいざ触ってみると分からない事だらけでした。  
次回の続きでDNSやADのもっと奥深いの書いてみたいですね。

PS.  
自宅にもWindows Serverあれば置いて運用してみたいですが、高いんだこれが...
バージョン指定して特定のマイグレーションファイルを削除する、ついでにNO FILEのマイグレーションファイルも消す

# はじめに
あんまりつかうことがないので忘れがちなマイグレーションファイルの削除について....

## statusでみる

```
& bundle exec rails db:migrate:status
```

```
up     202312250xxxx Delete hoge
up     202401091xxxxx  Add hoges
up     20240207xxxxxx  Change hoge body
up     2024030xxxxxxx  Add hoge messsage
```

## 消す
```
up     202312250xxxx Delete hoge
up     202401091xxxxx  Add hoges // これを消す
up     20240207xxxxxx  Change hoge body
up     2024030xxxxxxx  Add hoge messsage
```

downする
```
$ bundle exec rails db:down VERSION=202401091xxxxx
```
statusをみる
```
up     202312250xxxx Delete hoge
down     202401091xxxxx  Add hoges 
up     20240207xxxxxx  Change hoge body
up     2024030xxxxxxx  Add hoge messsage
```

いいね

次に消す
```
$rm db/migrate/202401091xxxxx_add_hoges_.rb
```

statusをみる
```
up     202312250xxxx Delete hoge
up     20240207xxxxxx  Change hoge body
up     2024030xxxxxxx  Add hoge messsage
```

消えてる。いいね。


# NO FILEになっちゃったマイグレーションファイルを消す
間違って消しちゃったりしたマイグレーションファイルがいる....

こんな感じのやつ

```
up 20xxxxxxxxxxxx  **********  NO FILE  **********
```

IDをコピーする
```
20xxxxxxxxxxxx
```

同じIDでダミーのマイグレーションファイルを適当な名前で作成
```
$ touch db/migrate/20xxxxxxxxxxxx_tekitou.rb
```
作成されたファイルを修正する
```ruby:20xxxxxxxxxxxx_tekitou.rb
class Tekitou < ActiveRecord::Migration[6.1]
  def change
      // 何も書かなくて良いです
  end
end
```

statusを見るとこうなっているはず
```
up 20xxxxxxxxxxxx Tekitou 
```
downする
```
down 20xxxxxxxxxxxx Tekitou 
```
消す
```
$ rm db/migrate/db/migrate/20xxxxxxxxxxxx_tekitou.rb
```
statusを見て消えているかどうかの確認をして終わり

# さいごに
こういうときたまにある。
【PyCaret】　回帰？分類？どっちで解く？

# はじめに
PyCaret　を使った機械学習モデル作成を最近始めました。
とっても便利ですね✨

さて、ある分類問題を解くために、サブモデルとして複数のモデルを作成したくなり、
サブモデルは、回帰・分類　どちらもある　という状況でした。

いざ作業すると、<strong>”分類問題”　なのに回帰モデルを作ってくる</strong>ではありませんか(´;ω;｀)

この解決方法をまとめました。

※PyCaretの概要については、下記まとめ　がとても参考になります！
https://qiita.com/Takumi_Fukuda/items/99e60793ac700974cfc4


# 結論

<strong>回帰問題</strong>　を解きたいときは、下記インポートを実行してから作業する。
```Python
from pycaret.regression import * #回帰のインポート
・・・
```

<strong>分類問題</strong>　を解きたいときは、下記インポートを実行してから作業する。
```Python
from pycaret.classification import * #分類のインポート
・・・
```

非常に、シンプルで簡単ですね！

コツは、<strong>何回でもインポートする</strong>　ことです。
※その他ライブラリは、コード上部で一度インポートすればOKという認識だったので、まさか最後にインポートした方で、モデル作成されるとは思ってもみませんでした。

# 直面した問題
すでに機械学習モデルに投入できるように、カテゴリ変数を数字に変換した状態でした。
よって、サブモデルの正解データが　｛0,1,2,3｝　のようになっているが、あくまで分類問題として予測したかった。

一方、notebook上では、上の方から回帰モデルを作成してきており、最後にインポートしたのは「regression」の方・・・。　えぇ、回帰モデルの出来上がりです。

結論にたどり着くまで、
・正解データを文字型（str）にする　⇒　数字として認識される。
・適当な文字を追加する。｛A0,B1,C2,D3｝　⇒　数字としては認識されないが、相変わらず回帰モデル。
といった、試行錯誤の上、解決しました。

# 最後に
どなたかのお役に立てば幸いです！
Git ブランチ名を Bash プロンプトに表示する方法とカラーコーディング

BashのコマンドプロンプトにGitのブランチ名を表示させることで、現在作業しているブランチを一目で確認できます。さらに、色を変更することで、プロンプトを見やすくカスタマイズすることが可能です。ここでは、Gitブランチ名の表示方法と色の設定方法を詳しく説明します。

#### Git ブランチ名を表示

1. **.bashrc ファイルを編集**:
   ターミナルで `.bashrc`または`.bash_profile` ファイルを開きます。
   ```bash
   vi ~/.bashrc  # または vi ~/.bash_profile
   ```

3. **カラーコードを使用したプロンプト設定**:
   次のコードを追加または修正してください。
   ```bash
   # Git branch in prompt.
   parse_git_branch() {
       git branch 2> /dev/null | sed -e '/^[^*]/d' -e 's/* \(.*\)/ (\1)/'
   }

   export PS1="\[\033[32m\]\u@\h\[\033[33m\]:\w\[\033[36m\]\$(parse_git_branch)\[\033[00m\] $ "
   ```
    この設定では：
   - ユーザー名とホスト名 が緑色
   - 現在のディレクトリ が黄色
   - Git ブランチ名  がシアン
   - `\[\033[00m\]` で色をリセットして通常のテキストカラーに戻します

#### カラーコードの設定

プロンプトの色は、ASCIIエスケープシーケンスを使用して設定します。以下に一般的な色のコードを10色紹介します。

| 色       | コード       |
|--------|------------|
| 黒       | `\033[30m` |
| 赤       | `\033[31m` |
| 緑       | `\033[32m` |
| 黄色      | `\033[33m` |
| 青       | `\033[34m` |
| マゼンタ    | `\033[35m` |
| シアン      | `\033[36m` |
| 白       | `\033[37m` |
| 明るい灰色   | `\033[90m` |
| 明るい青    | `\033[94m` |

#### 設定の反映

設定を反映させるためには、変更した.bashrcまたは.bash_profileファイルを再読み込みする必要があります。以下のコマンドを実行します。

```bash
source ~/.bashrc  # または source ~/.bash_profile
```

これで、BashプロンプトにGitのブランチ名が表示され、設定した色に応じて色付けされるようになります。このカスタマイズにより、複数のブランチを扱う際の作業効率が向上します。
Retrieval-based Voice Conversion WebUI (RVC WebUI) のインストール方法

**概要:**  
Retrieval-based Voice Conversion WebUIは、声の機械学習を効率的に行うためのツールです。ここでは、Ubuntu環境でのインストールと設定方法について説明します。

**事前準備:**  
- Ubuntu 20.04またはそれ以降のバージョンがインストールされていること
- Python 3.10がインストールされていること

### インストール手順

1. **リポジトリのクローン**
   - まず、公式のGitHubリポジトリからRVC WebUIのコードをクローンします。
   ```bash
   git clone https://github.com/liujing04/Retrieval-based-Voice-Conversion-WebUI
   cd Retrieval-based-Voice-Conversion-WebUI
   ```

2. **run.shの編集**
   - 仮想環境を作成するための`run.sh`を、Python 3.10を使うように編集します。
   ```bash
   nano run.sh
   ```
   - 具体的な変更箇所は次のとおりです：
     - `.venv/bin/python3.8` を `.venv/bin/python3.10` に変更します。

3. **仮想環境のアクティベート**
   - `run.sh`で作成された仮想環境をアクティベートします。
   ```bash
   source .venv/bin/activate
   ```

4. **不足しているパッケージのインストール**
   - 仮想環境内で、`run.sh`を実行するために必要な以下のPythonパッケージをインストールします。

   - **python-dotenv:**
     ```bash
     pip install python-dotenv
     ```

   - **numpy:**
     ```bash
     pip install numpy
     ```

   - **soundfile:**
     ```bash
     pip install soundfile
     ```

   - **torch:**
     ```bash
     pip install torch
     ```

   - **ffmpeg-python:**
     ```bash
     pip install ffmpeg-python
     ```

   - **av:**
     ```bash
     pip install av
     ```

   - **scipy:**
     ```bash
     pip install scipy
     ```

   - **faiss-cpu:**
     ```bash
     pip install faiss-cpu
     ```

5. **run.shの実行**
   - 必要なパッケージがインストールされ、環境が整ったら`run.sh`を実行します。
   ```bash
   sh ./run.sh
   ```

以上で、Retrieval-based Voice Conversion WebUIのインストールが完了し、起動することができるはずです。
Pythonでvenvを使用して仮想環境を構築するメモ

venv（virtualenv）は、プロジェクト毎に独立した仮想環境を作成することができる、Python3の標準ライブラリのこと。
`python -m venv <仮想環境名>`で作成できる。今回は仮想環境名をvenvとする。

## Windowsの場合
- 仮想環境を作成
```
python -m venv venv
```

- 仮想環境に移動する（アクティベート）
```
.\venv\Scripts\activate
```

- 仮想環境から離れる（ディアクティベート）
```
 deactivate
```

## Mac, Linuxの場合
- 仮想環境を作成
```
python3 -m venv venv
```
or
```
python -m venv venv
``` 

- 仮想環境に移動する（アクティベート）
```
source venv/bin/activate
```

- 仮想環境から離れる（ディアクティベート）
```
 deactivate
```

## 参考URL
https://docs.python.org/ja/3/library/venv.html
ElasticsearchのMachine Learning / 機械学習についての記事まとめ

これまでにElasticsearchが提供する機械学習系の機能を色々と紹介してきたので、ここでそれらの記事へのリンクをまとめる記事を書いておきたいと思います。


# Anomaly Detection / 異常検知

https://qiita.com/daixque/items/770f9560db12d8d88aba

https://qiita.com/daixque/items/7358726f5a6955476c94

https://qiita.com/daixque/items/8b450b1d30f7551fbdeb

https://qiita.com/daixque/items/fa0bded5f8a08297410e

https://qiita.com/daixque/items/30321e8a6047aba9b88c

https://qiita.com/daixque/items/9d1f9c66b8787dd6733a


# Data Frame Analytics / データフレーム分析

https://qiita.com/daixque/items/add938d86a253442d075

https://qiita.com/daixque/items/a9708a6e438a8f84fac4


# 機械学習を使った検索

## ベクトル検索 / セマンティック検索

https://qiita.com/daixque/items/d77305e3ebf082126c58

https://qiita.com/daixque/items/931b8be343075b835097

https://qiita.com/daixque/items/3c1beb343ea257aa351f


## Semantic text / Inference API

https://qiita.com/daixque/items/570ec008e69099e663bf

https://qiita.com/daixque/items/df699e8a2b318d593128

## リランキング

https://qiita.com/daixque/items/38e24704269adc9910b9

https://qiita.com/daixque/items/b80146c8247d59fb9f44


# LLM / AIアプリケーション開発関連

https://qiita.com/daixque/items/8f10d9812172ec8110b0

# 生成AI関連

https://qiita.com/daixque/items/eb406b66b4235e367350
私が学ぶLLM：①トークナイザについて

今日は、自然言語処理において非常に重要な役割を果たすトークナイザについて説明したいと思います。

# 1.トークナイザとは
自然言語処理を行う際、まず最初に行わなければならない作業が、文章をコンピュータが処理可能な形式に変換することです。つまり、文章を単語や形態素などの基本的な単位であるトークンに分割する必要があります。この作業をトークナイズと呼び、トークナイズを実行するためのモデルが「トークナイザ」です。トークナイズ実行のイメージは以下の通りです。（wikipedia-jpの数百MBのデータを用いて学習したトークナイザによる分割例）

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3556459/3c40a513-712c-d0dd-b7ae-580765f35610.png)

# 2.トークナイザの分割粒度
トークナイズの際には、主に3つの粒度”word”、”char”、”subword”があります。

Wordは最も自然な言語単位であり、特に英語などのスペースや句読点で単語が区切られている言語では、比較的容易にword単位で分割することができます。しかし、日本語や中国語などの漢字を使用する言語では、単語を分割するための特別なアルゴリズムが必要となります。一般的なvocab（tokenの辞書）のサイズは5万語以下であることが多いです。
Charは、アルファベットやひらがな、カタカナなどの文字単位です。（英語の'a'、'b'、'c'や日本語の'あ'、'い'、'う'など）ただし、charの文字数は限られているため、各文字のEmbeddingベクトルには多くの意味が含まれることになり、学習が非常に困難になるという問題があります。
Subwordは、charとwordの中間的な単位であり、両方の利点を取り入れた方法です。Subwordでは、頻繁に使われる単語はそのまま維持し、まれな単語はさらに分割するという処理を行います。（例えば、'Transformers'という単語を、'Transform'と'ers'の2つのsubwordに分割）文字数と意味の独立性のバランスを取ることができるため、今ほとんどのトークナイザはSubwordで分割します。

# 3.トークナイザでよく使われているアルゴリズム

最も一般的なトークナイザのアルゴリズムとしては、BPE（Byte-Pair Encoding）とSentencePieceが挙げられます。また、日本語の場合は形態素解析も使われてます。
BPEは、比較的前からあった基本的な手法で、最も頻繁に出現するSubwordペアを順次マージしていき、語彙数が予定のサイズに達するまで続けるという考え方に基づいています。
一方、形態素解析は日本語特有のアルゴリズムです。日本語では単語間にスペースがないため、単語の分割位置を特定するのが難しいという問題があります。そのため、MeCabなどの形態素解析器を用いてテキストを事前に分割し、その後にBPEやWordPieceなどで分割を行います。（中国語も同様の特性を持つため、中国語のトークナイザーでも形態素解析は実施します）
ただ、形態素解析による単語の事前分割は日本語では効果的ですが、他の言語には適用できないため、汎用性からは課題があります。この課題を解決する手法の一つが、SentencePieceです。SentencePieceは、Googleが公開されているオープンソースのトークナイザーであり、テキストを事前に単語で区切るのではなく、分割方法そのものを生の文章から直接学習するというアプローチを取っています。

具体的には以下の4つの処理を行います。
Unicode Normalization:テキストデータを正規処理
Trainer：Subword単位の分割方法を学習
Encoder：テキストをSubword単位に分割
Decoder：分割されたテキストを元のテキストに復元

簡単に言うと、SentencePieceは、Encoderでテキストをsubword単位に分割し、Decoderで元のテキストに復元するトークナイザーだと言えます。

詳細については⇩の論文で説明されています。興味ある方ご覧ください：

https://arxiv.org/pdf/1808.06226，

こちら⇩も参考になれます：

https://huggingface.co/docs/tokenizers/quicktour

https://www.macromill.com/service/words/morphological-analysis/#:~:text=%E5%BD%A2%E6%85%8B%E7%B4%A0%E8%A7%A3%E6%9E%90%E3%81%A8%E3%81%AF%E3%80%81%E8%87%AA%E7%84%B6,%E3%80%81%E3%80%8CMeCab%E3%80%8D%E3%81%8C%E6%9C%89%E5%90%8D%E3%80%82
AWS SQS/Lambda/SNSにS3を連携し、メール通知を行ってみる[03]

こんにちは。
株式会社クラスアクト インフラストラクチャ事業部の大塚です。

今回はAWS SQS,Lambda,SNS環境にS3を追加して、S3に何らかのデータがアップロードされた際にメールが通知される環境を構築していきたいと思います。

前回の記事は以下となります。

https://qiita.com/ohtsuka-shota/items/4daaf14c03705ee0ad05

全体の流れは以下にまとめています。

https://qiita.com/ohtsuka-shota/items/db74a418dabc261d9126

# 最終的な構築イメージ
以下環境を作っていきます。今回はS3を実装していきます。
![aws-django01-ページ6.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/426843a2-5d28-7283-96dc-22fb1cbe3e34.png)

# 構築
## S3の作成
バケットの作成を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/95b75e9a-a03b-9e84-eb40-d5c1299058ca.png)
以下の設定で作成していきます。基本的にデフォルトの設定から変更していません。
- バケットタイプ：汎用
- バケット名：qiita-s3-qiita

![screencapture-ap-northeast-1-console-aws-amazon-s3-bucket-create-2024-05-01-20_26_15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/e82bd442-2739-81e2-7a39-fd572fb809e6.png)
S3が作成されたことを確認します。Arnはこの後使いますので控えます。
![2024050114.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/336799ea-af1d-6dd4-63a7-d9e264515c28.png)

## SQSのアクセスポリシー編集
S3に紐づけたいSQSの管理画面に移動します。
アクセスポリシータブ内にあるアクセスポリシー（アクセス許可）を編集していきます。
![2024050115.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/f768a2d8-d445-e4f1-aecd-58b7ffafe9c9.png)
以下の内容に修正して保存します。
```
{
  "Version": "2012-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__owner_statement",
      "Effect": "Allow",
      "Principal": {
        "Service": "s3.amazonaws.com"
      },
      "Action": "sqs:SendMessage",
      "Resource": "★SQSのArn★",
      "Condition": {
        "ArnLike": {
          "aws:SourceArn": "★S3のArn★"
        }
      }
    }
  ]
}
```

## S3のイベント通知設定
S3のプロパティタブにイベント通知の欄があります。
イベント通知の作成を押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/880e54f9-eed4-bb8a-44b9-79bfae998f9a.png)
以下の設定で保存します。
- イベント名：call_qiita_sns
- イベントタイプ：オブジェクトの作成：PUT
- 送信先：SQSキュー
- SQSキューを特定：SQSキューから選択する
- SQSキュー：qiita_sqs

![screencapture-ap-northeast-1-console-aws-amazon-s3-bucket-qiita-s3-qiita-property-notification-create-2024-05-01-20_41_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/67838e9c-0452-d20b-bac5-a5ad2d23d955.png)
イベント通知に表示されていることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/900f1202-7ed6-7ef0-1e49-2e1d82914e95.png)

## テスト
S3バケットにデータをアップロードすることでメール通知の処理が走るかを確認してみます。
今回作成したバケットを選択し、アップロードを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/505e1a05-1abc-de4e-84a8-16357e341067.png)
ファイルを追加ボタンを押下するとローカルのexplorerが立ち上がりますので、任意のデータを選択します。
アップロードを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/007625e3-b7e9-09e2-b92e-e261c50e30ac.png)
アップロードが成功していることを確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/d270e978-ec1f-0ab7-9dc7-8b0fd28a344c.png)
SNSで登録したメールアドレス宛に通知が飛んでいれば成功です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3219385/3a7525ba-ce06-2e41-b0f9-d73afca1ee4e.png)
GraphQL Rubyでfieldを共通利用したい

graphql-rubyを利用する際、複数のObjectで同一のfieldを共通利用したくなりました。
下記手順で、Interfaceを利用して実現できました。

1. BaseInterfaceを定義する
2. 共通利用したいfieldをまとめたInterfaceを定義する
3. fieldを定義するObjectでInterfaceをimplementsする

なお公式ドキュメントは下記です。詳細はこちらをご参照ください。
https://graphql-ruby.org/type_definitions/interfaces

# 0. Interfaceとは

> Interfaces are lists of fields which may be implemented by object types.

Interfaceとは、Objectによって実装することができるfieldのリストです。

# 1. BaseInterfaceを定義する

これから定義するInterfaceにおいて、その基底となるBaseInterfaceを定義します。

```ruby:types/base_interface.rb
module Types::BaseInterface
  include GraphQL::Schema::Interface
end
```

# 2. 共通利用したいfieldをまとめたInterfaceを定義する

例として、 `created_at` , `updated_at` というfieldを共通利用したい場合を想定します。
下記のようにInterfaceを定義します。

```ruby:types/timestamp_interface.rb
module Types::TimestampInterface
  include Types::BaseInterface

  field :created_at, GraphQL::Types::ISO8601DateTime, null: false
  field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
```

# 3. fieldを定義するObjectでInterfaceをimplementsする

例として、 `User` , `Book` というObjectで `created_at` , `updated_at` というfieldを定義している場合を想定します。

## Before

共通化する前は、それぞれ `created_at` , `updated_at` のfieldを定義していました。

```ruby:types/user.rb
class Types::User < Types::BaseObject
  field :name, String, null: false
  field :created_at, GraphQL::Types::ISO8601DateTime, null: false
  field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
```

```ruby:types/book.rb
class Types::Book < Types::BaseObject
  field :title, String, null: false
  field :created_at, GraphQL::Types::ISO8601DateTime, null: false
  field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
end
```

## After

先ほど定義した `TimestampInterface` をimplementsしました。
こうすることで、 それぞれで `created_at` , `updated_at` のfield定義が不要になりました。

```ruby:types/user.rb
class Types::User < Types::BaseObject
  implements Types::TimestampInterface

  field :name, String, null: false
end
```

```ruby:types/book.rb
class Types::Book < Types::BaseObject
  implements Types::TimestampInterface

  field :title, String, null: false
end
```
継承

## はじめに

継承についてまとめる

### 継承とは

基になるクラスの機能(メソッド)を引き継ぎながら、新たな機能を追加したり、元の一部だけを修正したりする仕組み。

#### 参考コード

BusinessPersonクラスがPersonクラスを継承している。

```php:Person.php
class Person
{
    public $firstName;
    public $lastName;

    public function __construct($firstName, $lastName)
    {
        $this->firstName = $firstName;
        $this->lastName = $lastName;
    }

    public function show()
    {
        print "<p>私の名前は{$this->lastName}{$this->firstName}です。</p>";
    }
}
```

```php:BusinessPerson.php
require_once 'Person.php';

class BusinessPerson extends Person
{
    public function work(): void
    {
        print "<p>{$this->lastName}{$this->firstName}は働いています。</p>";
    }
}
```

```php:extends.php
require_once 'BusinessPerson.php';

$bp = new BusinessPerson('鈴木', '太郎');
$bp->work(); // 鈴木太郎は働いています
$bp->show(); // 私の名前は鈴木太郎です
```


`BusinessPerson`クラスで定義された`work`メソッドだけでなく、親クラスである`Person`クラスで定義されたコンストラクターや`show`メソッドをあたかも`BusinessPerson`クラスのメンバーであるかのように呼び出すことができている。

#### どんなときに継承を使うべきか

親クラスと子クラスにis-aの関係が成り立つとき。
→「SubClass is a SuperClass」であるとき

参考コードにおける、`class BusinessPerson extends Person`というコードは、
「`BusinessPerson`(ビジネスパーソン)は`Person`(人間)」であるため、継承は使い道として適切。

間違った例を挙げると、`class BusinessPerson extends Food`というコードは
「`BusinessPerson`(ビジネスパーソン)は`Food`(食べ物)」ではないことから、使い道として適切ではない。
会員登録後のメールアドレス、パスワードの保存モーダル表示は実装で制御可能ですか？

【場面】
Webアプリケーションの会員登録フローにおいて、メールアドレスとパスワードを設定してもらった後

【やりたいこと】
このようなメールアドレスとパスワードの保存を促すWebブラウザのモーダルを会員登録直後に常に出したい

【聞きたいこと】
このような表示は、Webブラウザの挙動なので制御できないのかor実装で制御可能か


#アカウント情報の保存
#モーダル![IMG_9913.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/550129/42da1dee-24d0-9f88-d98c-ca167a03aff6.png)
WordPressでうっかり所有者（パーミッション）が変わってFTPでアップロードできなくなった時の、コマンドを使わない対処法

## はじめに
WordPressの「All-in-One WP Migration」などをつかって引越しをした際など、ディレクトリやファイルの所有者が「apache」などになってファイルのアップロードや削除ができなくなることがあります。
よくある解決法として、「chownコマンドで所有者 / グループを変更する」というものがありますが、今回は**コマンドを使わず**に解決してみたいと思います

## 結論
WordPress自身であればディレクトリやファイルの削除ができる可能性があります。

## 解決法
WordPressのプラグインに「管理画面内でFTP操作ができる」ものがあります。
たとえばこちら。
https://ja.wordpress.org/plugins/wp-file-manager/

このプラグインを用いればディレクトリやファイルの削除ができる（可能性がある）ので、所有者が変わってしまったファイルたちを削除し再度FTPソフトでアップロードしてあげれば大丈夫。


## 終わりに
「All-in-One WP Migration」がフォルダやファイルを生成しているのでWordPress側がどうこうできるのはよくよく考えたら当たり前なのですが、これに気づくのに少し時間がかかりました。
社内の過去の案件でもたまに「なぜか所有者が違っていてファイルの削除ができない」みたいなのがあるのでもしかしたらこれで解決できるのかも。
日本語を含むURLを文字化けせずにコピペする方法

日本語を含むURLを文字化けせずにコピペする方法です。
ちょっと稚拙ですけど、僕にとっては便利だったので共有

1. ブラウザのURL欄より先頭の ’h’ を除いてコピーします。
2. ペーストした後、その先頭に’h’をつけます。


Enjoy!

キーワード：
　 　 パーセントエンコーディング
Salesforceでフローを作成しよう～商談に同じ商品を選択した場合にエラーを発生する方法～

本橋孝昭です

今回はSalesforceでフローを作成する際に
「商談に同じ商品を選択した場合にエラーを発生する方法」を紹介します

今回の内容は動画でも解説しています

https://youtu.be/s4h-recjTRs?si=lG8fboudT76VfGFH

<iframe width="560" height="315" src="https://www.youtube.com/embed/s4h-recjTRs?si=lG8fboudT76VfGFH" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

このフローを作成すれば、商談商品作成時に同じ商談と商品がある場合エラーが出る設定を行うことが出来ます。


なお、商談商品、商談、商品についてのオブジェクトの構成についてはこちらとなります


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c0e0c127-c7f7-15a3-d9d6-4c2d663819c7.png)

商談商品、商談、商品について詳細確認したければこちらをご確認ください

https://qiita.com/Takaa/items/75c2b39eb08ec79aec48

こちらのフローを作成すれば、もしも商談に商品を追加する際にすでに同じ商品がある場合、このようにフローでエラーメッセージを表示することが可能です

![商談商品001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/15455359-bcdc-d71b-650f-b0e161fee426.png)


それではフローの設定画面を見ていきます

## フロー全体像

![01フロー確認.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/39c4d29b-5816-82b6-a694-74aa42e30368.png)


## フロー詳細
![002フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/e31309b7-27c0-cc76-1b30-5427c8f447b3.png)

※最後のANDは　ID　次の文字列に一致しない　{!$Record.Id}　です


![003フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d43c875c-c69d-7ddf-0977-5f8811b71ab0.png)


![004フロー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/c7bf6fb8-e689-06bf-8fd8-adfb72a08fea.png)


※もちろんエラーメッセージは任意で大丈夫です
今回は例としてこのようなエラーメッセージを作成しました

>商談と商品で全く同じデータのものがあります。
こちら同じものがすでにあるので保存はできないです。
同じデータはこちらです
https://wise-koala-1v6x88-dev-ed.trailblaze.lightning.force.com/lightning/r/Child__c/{!GetOpportunityLineItem.Id}/view



なお、このURLは例でありSalesforce環境により異なります
（「wise-koala-1v6x88-dev-ed.trailblaze.」は他環境により異なります）
もしもそちらの環境で設定したい場合、商談商品オブジェクトのレコード（なんでもいいので）を開きそのURLをコピペして貼ることが確実です

![商談商品0001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/31237ef0-396d-7d4c-3368-e1594460807c.png)



以上の設定をすればこのようなエラーメッセージの表示が可能です

![商談商品001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/15455359-bcdc-d71b-650f-b0e161fee426.png)
機能設計のタイミング

いつもぼやっとして忘れてしまうので、どこかに書いておこうかと思っていた内容のメモ。
同僚のプロジェクトマネージャーのMAOKIN氏から説明してもらった、要件定義時の工程の順番。

システムのタイプによって着手順番を間違うと、要件定義や基本設計のフェーズで手戻りが大きくなってしまう。例えば業務系システムを作るのにデザインから始めてしまうと、データ設計と辻褄が合わないとか出てきて手戻りが発生してしまってことがあるので、気をつけよう（と自分に言い聞かせている）

| システムの分類 | 目的 | 先に着手すること |
|:-|:-|:-|
| エンターテインメント系   | エンゲージポイントを高める | デザイン・世界観 |
| 業務システム・サービス系 | 機能の整理・抽出        | 機能設計・アクティビティの整理 |
MySQLのdocker-compose最小構成設定

# MySQLのdocker-compose最小構成設定
- docker-compose.yml
```yaml:docker-compose.yml
services:
  db:
    image: mysql:latest
    volumes:
      - ./db/datadir: /var/lib/mysql
      - ./db/backups: /data/backups
    env_file:
      - project.env
    ports:
      - 3306:3306
  #app:
    # ...
```

- project.env
```yaml:project.env
MYSQL_ROOT_PASSWORD="password"
MYSQL_DATABASE="dbname"
TZ="Asia/Tokyo"
```

## ディレクトリ構成
- Dockerfileはオプション
```bash:
./projectdir
    docker-compose.yml
    project.env
    db/ #ビルド時に生成
        datadir/ #ビルド時に生成
        backups/ #ビルド時に生成
    # app/
    # Dockerfile
```


## ビルド
- docker-compose.ymlと同じディレクトリで実行
```bash:
docker-compose up -d
```

## アクセス
- ホストからコンテナのmysqlにログイン
```bash:
mysql -u root -p -h 127.0.0.1 -P 3306
```
- ホストからコンテナ内に入り、コンテナ内でmysqlにログイン
```bash:
docker exec -it ContainarName bash
mysql -u root -p 
```

# 参考
- [mysql公式イメージ - hub.docker.com](https://hub.docker.com/_/mysql)
- [Docker公式リファレンス - docs.docker.com](https://docs.docker.com/reference/)
- [Docker ドキュメント日本語化プロジェクト - docs.docker.jp](https://docs.docker.jp/index.html#)
- [Compose file specification - github.com](https://github.com/compose-spec/compose-spec/blob/master/00-overview.md)

# 前提
- 2024/04 版
- 必要最低限のとりあえず動く設定を作る
- ベストプラクティスを目指す
- 環境
    - WSL2+Ubuntuの構成
    - DockerDesktopを使用
- 運用
    - ホストのhomeディレクトリから各用途に合わせてプロジェクト用のディレクトリを作り、各プロジェクト内でDockerfile、docker-compose.ymlを管理する
    - docker-compose.ymlはGitで管理して開発者間でビルド情報を共有する
    - 公式Dockerイメージ(Dockerfile)には可能な限り変更は加えない
        - DBに変更を加えたい場合はデータマウントを活用する
        - やむを得ずDockerfileに変更を加える場合は作成したDockerイメージをDockerHubで管理する

# docker-compose.ymlレシピ
## サービス名をつける
```yaml:
services:
    db:
    # app: 
```
## imageまたはbuildを選択
### image
- DockerHubのイメージを直接使う場合に記載(Dockerfileを使用しない)
```yaml:
services:
    db:
        image: mysql:5.7
```
### build
- Dockerfileを使用する場合に使用、Dockerfileの相対パスを指定
```yaml:
services:
    db:
        build: ./projectdir
```
## volumeの形式を選択
- ボリュームを使うとデータはDockerコンテナの起動・停止のサイクルから独立してホストマシンとデータを共有・管理できる
### volumes(サービス内)
```yaml:
services:
    db:
      volumes:
          - ./db/datadir: /var/lib/mysql
```

### volumes(トップレベル)
- コンテナ間でボリュームを共有したい場合に使用する
- Dockerの管理下```/var/lib/docker/volumes```でストレージ領域を確保される
```yaml:
services:
    volumes:
    - db_data: /var/lib/mysql
volumes: 
  db_data:
```

- マウントポイントはコマンドで確認できる
```bash:
docker volume ls
docker volume inspect [volume name]
```

### 環境変数を設定する
- .envファイルでコンテナ内で使用する環境変数を書いてインポートできる
    - パスワードなど共有したくない情報はローカルで管理する
```yaml:
services:
    db:
        env_file:
          - project.env
```

### ポート指定
- ホスト→コンテナへポートフォワードの設定ができる
- ホストマシンのポート番号：コンテナのポート番号
```yaml:
services:
    db:
        ports: 
            - "3000:3000"
```
### 依存関係(option)
- 起動順序をつけたいとき
```yaml:
# 例：db起動後にappから接続したい場合
services:
    app:
        depends_on: 
             - db
```
### version(option)
- 古いバージョンを指定したいときに使う
PAD(Problem Analysis Diagram)をExcelで描くためのテンプレートの提案

# ロジックを可視化するにはPADが有効
プログラミング経験者の方で『仕様のロジックを可視化するために、フローチャートを描いたけど処理の構造がはっきりしない。』といった悩みや、これからプログラミングを始めようと考えている方で『仕様をプログラムに落とし込むためには、何をやればいいのか分からない。』という不安を解決するには、プログラムロジックを誰が見ても分かりやすい図に表すことが必要です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128425/40c22d17-54cf-18e6-c2ef-9d85f7c86640.png)

プログラムのロジックを表現する方法としては、フローチャートがよく知られていますが、PADは、フローチャートの欠点を補って、さらに論理構造をすっきりした形で可視化することが可能な図面です。
PADを使うと、論理構造を目で見て理解しやすく可視化することができるので、頭の中をすっきり整理することができます。

JIS規格に「プログラム構成要素及びその表記法」というのがあって、手続き的アルゴリズムの制御構造を表現する方法を定義していて、フローチャートやPADなどいくつかの表記方法が紹介されています。
https://kikakurui.com/x0/X0128-1988-01.html

PADを推奨する理由は、「仕様が決まっていれば誰が描いても同じものになる」からです。誰が描いても同じものになるので、誰が見ても分かりやすいということです。

Qiitaの下記投稿で紹介されているので、ここでは説明は省略します。
https://qiita.com/madilloar/items/1455245130ba0e94f7df

# PADをExcelで描きたいときの悩み
ロジックの可視化にPADが有効なことは分かっていても、Excelを使ってPADを描こうとすると、PADで使う一部の図形が、Excelの図形のテンプレート「フローチャート」の中に無いので、フリーフォームで図形を用意する必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128425/858a77ff-8035-5fc8-7357-373098d08d50.png)

さらに、ExcelでPADを描いてみて一番面倒だったのは、常に図形を左揃えにしなければならないことでした。ロジックを可視化して頭の中を整理したいのに、絵を描く作業に時間を費やすことになって、モヤモヤした気持ちになりながらPADを描くことになります。

# 左揃えはVBAで自動化する
そこで私が提案したいのは、左揃えボタンをクリックすることで適当に配置した図形を左揃えする処理を実装した、PAD作成用のExcelテンプレートファイルを用意しておくことです。このテンプレートがあれば、案外ExcelでPADを描くというのが現実的になるんじゃないでしょうか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128425/c9a0d7cd-5363-3861-5e15-d4f0a55dd9b5.png)

# まとめ
PADは私が新卒で会社に入社してから間もない時に教わったのですが、簡単な描き方のルールさえ覚えれば、誰でも使えるようになりますから、40年以上経った今でもスラスラ描けてしまいます。全く廃れることのない素晴らしい設計手法だと思います。
作成したPADをデザインレビューに回すとしたら、レビューアのコメントを追記したくなりますし、ドキュメントとして残す場合は、ロジックだけではなくて処理の意味を記載しておくことも必要になります。そんなとき便利なのは、やっぱりExcelじゃないかなと考えて、PADをExcelで描くためのテンプレートのアイデアについて書きました。

# 関連動画
[プログラムロジック設計講座　PAD(Problem Analysis Diagram)でロジックを可視化する](https://www.udemy.com/course/problemanalysisdiagram/?referralCode=D6B4BF783057773242F7)
About NestJS

NestJS について。

https://nestjs.com/

Product の技術選定を行なっている。

今後の開発を見据えて、技術選定を行う。
わたしが考えている技術選定の前提条件は以下の通りである。
1. 少人数で適切なスピード感で開発できる。
1. メンバーの共通の技術スタックである。
1. (1)(2)を満たしつつ、アプリケーションの複雑さを将来に持ち込まない構成である。

現状の方針として考えられるのは
1. Framework を活用する。
    - ❓
2. 開発言語を最小限にする。
    - TypeScript
3. DDD と modular monolith pattern を採用する。

❓ の Framework について検討した。

今回の code はこちら。

https://github.com/danny-yamamoto/nestjs-sample.git

## About NestJS
- NestJS は Express をベースした Framework である。[^3]
- 今私が欲しい機能は、大体揃っている。
> ChatGPT
> NestJS は、Node.js のためのフル機能のサーバーサイドアプリケーションフレームワークです。Angular の開発者が使いやすいように設計されており、Angular のスタイルと構造にインスパイアされたものです。NestJS は、エクスプレスをベースにしており、エクスプレスのパワフルな機能を活用しながら、アプリケーションの構造化と保守性を向上させます。
> 
> NestJS の主な特徴や利点には以下が含まれます：
> 
> 1. **モジュールベースのアーキテクチャ**: アプリケーションをモジュールに分割し、それぞれのモジュールが独立して機能するように設計されています。これにより、アプリケーションが拡張可能でテストしやすくなります。
> 
> 2. **依存性注入 (DI)**: NestJS は、依存性注入を使ってコンポーネントやサービスを管理します。これにより、コードの再利用性とテスト容易性が向上し、コードの冗長性が減ります。
> 
> 3. **ミドルウェア**: NestJS は、エクスプレスのミドルウェアを簡単に統合できるため、リクエストとレスポンスの処理を柔軟に制御できます。
> 
> 4. **WebSocketsのサポート**: NestJS は、WebSocket のサポートも提供しており、リアルタイムな通信アプリケーションの開発が容易です。
> 
> 5. **スケーラビリティ**: NestJS は、標準的な Node.js のスケーラビリティ戦略に従っており、クラスタリング、ロードバランシング、マイクロサービスアーキテクチャなどの手法を使用して、アプリケーションのパフォーマンスを向上させることができます。
> 
> NestJS は、TypeScript で書かれており、静的型付け言語の恩恵を受けることができます。このため、開発プロセスがより安全で効率的になります。

## Architecture
- NestJS は module で構成できる。

https://github.com/danny-yamamoto/nestjs-sample/blob/main/src/app.module.ts

- API の雛形を generate してくれる。誰が実装しても構成を統一できることは大きなメリットだと思う。`nest g resource [name]`
- Domain logic は `xxx.service.ts` に実装する。

https://github.com/danny-yamamoto/nestjs-sample/blob/main/src/users/users.service.ts

```mermaid
flowchart TD
    app_module["app.module.ts
    [generated]"]
    sample_module["users.module.ts"]
    main["main.ts
    [generated]"]
    sample_controller["users.controller.ts"]
    sample_service["users.service.ts"]
    db1[(Database)]
    start --> client
    client --> app_module
    app_module --> main
    app_module --> sample_module
    sample_service --> db1
    subgraph sample["users module"]
        sample_module --> sample_controller
        sample_controller --> sample_service
        sample_module --> sample_service
    end
```

## Schema definition
- NestJS は Web API を OpenAPI[^4] 形式で共有できる。[^1]
- NestJS は Swagger を提供している。GraphQL Playground も。[^2]
- IMO, API は開発した後が重要だと思う。なぜなら、どの会社でも「API の仕様を教えてください。」というやり取りを目にするから。
> The OpenAPI specification is a language-agnostic definition format used to describe RESTful APIs. Nest provides a dedicated module which allows generating such a specification by leveraging decorators.
>
> OpenAPI仕様は、RESTful API を記述するために使用される、言語にとらわれない定義フォーマットである。Nestは、デコレータを活用してこのような仕様を生成できる専用モジュールを提供している。

![alt text](/images/7e5fd225cc8041-a.png)

## BTW
新しい職場のオンボーディングや業務理解が落ち着いてきた

そして、気づけば GitHub の草が枯れ始めていた 🌱

事業ドメインへの理解（Why）を深めつつ、最適な課題解決の How を提供できるよう Engineer として学びを深めていきたい

[^1]: https://docs.nestjs.com/openapi/introduction
[^2]: https://docs.nestjs.com/graphql/quick-start
[^3]: https://docs.nestjs.com/
[^4]: https://www.openapis.org/
R6春_応用情報受験記録

# はじめに
令和6年春季の応用情報技術者試験を受けてきたので，勉強方法や当日の感想などを記録として残しておきたいと思います．

# バックグラウンド
情報系の大学院生で，少しだけネットワーク・サーバー周り触ってたりセキュリティの勉強したりしてます．
基本情報は大学2年生？3年生？の時くらいに取得して，応用情報は大学4年生の時に一度受験しましたが，午後試験に58点で落ちました．(答案回収された後に，一か所間違いに気づいてしまいました…)

# 勉強した期間
勉強を始めたのが，3月の中旬くらいで試験が4月21日だったので，1カ月と少しくらいで時間的には平均して毎日2-3時間くらいだと思います．

# 午前対策
午前試験は全部で80問出題され，60%以上正解で合格となります．なので48問以上ですかね．
[テキスト](https://direct.gihyo.jp/view/item/000000001301)を軽く1回読んであとはひたすら[過去問道場](https://www.ap-siken.com/apkakomon.php)をずっとやってました．

応用情報の午前は半分以上が過去問からの出題なのでいかに過去問演習できるかだと思います．
(ちなみに直近2回分で出題された問題は出題されないらしいです．)
僕は直近2回を除いて10回分の問題を正解するまで繰り返ししてました．10年分解くのはかなり大変(特にマネジメント周り)ですが，過去問から出るとわかっている以上やらない手はありません．
＊過去問道場を使う場合はアカウント作ることをお勧めします．間違えた問題や分野別の正答率とかも見れるのでかなり便利です．

# 午後対策
午後試験は，情報セキュリティ必須で残りは
1. 経営戦略
1. プログラミング
1. システムアーキテクチャ
1. ネットワーク
1. データベース
1. 組込みシステム開発
1. 情報システム開発
1. プロジェクトマネジメント
1. サービスマネジメント
1. システム監査

この中から4問選択の計5問選択で各大問20点ずつです．
午後も基本的に過去問をひたすらやりました．
この際に全ての大問を全て対策するのは時間的にまず無理なので，対策の段階で当日解く候補を絞っておきましょう．

僕はプログラミング，ネットワーク，データベース，組込みシステム，システム監査を対策してました．

情報セキュリティは必須なので対策をせざるを得ないのでそれ以外で4-5問ほど対策しておけば当日，対策したなかのどれかが難しくても他の問題に切り替えられると思います．

午後の対策をする中で僕が気を付けていたことは，記述問題と解答の仕方です．
字数制限などがある問題では指定されている文字数の8-9割くらいで，なるべく本文の言葉を使って答えるようにしましょう．この時に，解答のキーワードとなるものを含めるように書くことを意識するとよいかもしれません．

# 前日・当日の過ごし方について
前日はひたすら午前を解いてました．午後は直前でやって伸びるものではないかなという感じがしてます．
何なら前日はゆっくりしてもいいかもしれません．とにかく前日に詰め込むようなことはせずに早く寝ましょう．

当日はまず試験開始時間までに会場にたどり着けるように少し早いくらいに起きるのがいいかもしれません．
そして朝ごはんをしっかり食べましょう．

:::note info
受験票に顔写真が貼ってあるか，時計を忘れていないかなどに気を付けましょう！
:::

# 受験の感想
まずは午前試験，オブジェクトストレージやら，ドキュメンテーションジェネレーターなどの知らない単語が出てましたが，意外と単語の雰囲気とかで正解できました．
午前はかなり時間に余裕があったので軽く見直しして退出しました．

次は午後試験，当日は情報セキュリティ，ネットワーク，データベース，組込みシステム，システム監査を選択しました．過去問解いても少し思いましたが，最近のプログラミングは昔と比べて全体的に難しいような？という感じがしてます．

セキュリティはゼロトラストが話題になってますが，僕も最初，「ブラックボックス・ホワイトボックス」当たりの単語が浮かんでましたが，最終的には解けたので良かったです．普段のセキュリティの勉強が役だったかなと思います．

# 自己採点結果
午前は公式解答で採点して，63/80で得点率78%なので午前は通過してました．
午後は資格予備校の解答速報で70%くらいでした．

合格発表までまだかなりあるので気ままに待ちたいと思います．受かってるといいなぁ…

応用情報合格してたらネスぺとりたいと思ってたんですけど，秋はネスぺがないということで支援士を受けるか悩んでるところです…
WebP導入の前にメリットデメリットを知っておこう

## なぜ今WebPが話題？

WebPは、Googleが開発した、軽量かつ高画質な画像形式です。

発表されたのは2010年と、結構前から存在していましたが、近年まで導入はほとんど進んでいませんでした。

というのも、IE（インターネットエクスプローラー）でWebPが未対応だったのが大きな理由です。2022年6月にIEがサービス終了したことで、選択肢の一つとして一気に現実味を増しました。

Googleトレンドを見てみても、IEがサ終する直前に一気に話題度が上がっていることがわかります。
![スクリーンショット 2024-05-01 190006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1902958/c1fcc6f4-4205-439c-9bed-7389ed34b00e.png)


今この記事を読んでいるあなたも、最近WebPの存在を知り、導入を検討している一人なのではないでしょうか？

導入前に、メリットとデメリットを理解しておきましょう。

## WebPのメリット

WebPのメリットは、何と言っても容量が軽いことです。

同等の画質であれば、JPEGよりも20～80％程度軽量化できます。

画像容量が小さい方が、Webページが表示されるスピードが早くなるので、ユーザビリティ的にもSEO的にも非常にありがたいです。

また、WebPは多少圧縮しても画質はほとんど劣化しません。

さらに、png形式同様、透明な部分もしっかり表現できます。

## WebPのデメリット

ここまで聞くと、WebP最強じゃん！と思うかもしれません。

しかし、WebPはあくまで、**ウェブサイト上で画像を表示するのに適したフォーマットである**ということを知っておかなければなりません。

例えば、Windowsの標準画像アプリで画像編集して保存すると、jpg形式で保存されてしまいます。（macは持ってないのでわかりません😭わかる人いたらコメント欄で教えてください🙏）

またパワポやエクセルにWebPを直接貼り付けようとしても、対応していないので、jpgやpngに変換する必要があります。ちなみにQiitaも貼り付けできませんでした...

あと、フォトショイラレから直接WebP形式で書き出すことができません。（[プラグイン](https://www.adobe.com/jp/creativecloud/file-types/image/raster/webp-file.html)を導入すればできるみたいです）

こういった場合にいちいち変換されるorする必要があるのが地味に面倒くさいところです。

## 画像をWebP化するには？

画像をWebP変換するツールは色々あります。

### Squoosh
Google純正の変換ツールです。オンラインツールですが、画像はサーバーには送信されておらず、ブラウザ上のみで行われてるようなのでセキュリティも安心です。

https://squoosh.app/
    
### サルワカ道具箱
複数の画像を一括で変換できます。

https://saruwakakun.com/tools/png-jpeg-to-webp/

    
### コマンドライン
WebPの公式サイトが提唱している方法です。
コマンドに慣れてないとちょっぴり難しいですが、詳細なカスタマイズや自動化ができます。

https://developers.google.com/speed/webp/docs/using#using_cwebp_to_convert_images_to_the_webp_format

## まとめ
もし、ページのファーストビューもしくはページ上部に容量の大きい画像が使われていたり、画像が大量に存在するページの場合、WebPに変換するのが特に有効です。

Webサイト上にある既存の画像をWebPに変換する場合、ソースの末尾を「.webp」に変更する必要があるので注意しましょう。
【知見メモ】wordJoinerでSwiftUIのText()の文字を変な位置で改行させないようにする方法

# はじめに

本記事では、wordJoinerを使って、SwiftUIのText()の文字を変な位置で改行させないようにする方法をご紹介します。

## 環境

- Xcode 15.2
- iOS 17.2

# 発生した課題

SwiftUIのTextを表示した時に、左詰めで文字が表示されず、変な位置で改行されていました。

![スクリーンショット 2024-05-01 18.12.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/eaea822f-d85d-b518-4cf7-33891eca495c.png)


```
現状: ボヘミア\nン・ラプソデ
```

しかし、理想とする改行の位置はこちら

```
理想: ボヘミアン\n・ラプソデ
```

（正式名称は、ボヘミアン・ラプソディですが、文字数の都合上、「ィ」は省略）

## 実装（before）

また、実装は下記の通りです。
ZStackでRoundedRectangleの上にTextを載せています。

frameを決めて、そのframe幅におさまるようにテキストを表示しています。

```swift
struct SampleView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 10)
                .foregroundStyle(Color.gray)

            Text("ボヘミアン・ラプソデ")
        }
        .frame(width: 96, height: 96)
    }
}

#Preview {
    SampleView()
}
```

# 原因

あくまで予想ですが、「・」が行の先頭に配置されないように、内部で調整されていると考えました。

実際に、文字の改行パターンを調査しました。

## 「・」を消して「ラ」を追加した時のケース

「ラ」を追加すると、左詰めで表示される。

![スクリーンショット 2024-05-01 18.11.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/666353ab-4ab4-ea66-4591-1ed9cfc6434f.png)


## ひらがなのケース

ひらがなも同様に「・」が先頭に配置されないように改行されてしまいます。

![スクリーンショット 2024-05-01 18.13.37.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/2380e90e-6acc-c9ba-7c19-7451b2d4f98b.png)



# 解決策

## 前提

今回の要件は下記の通りです。
- 「・」の有無関係なく、文字が左詰めになっていること
- どんな文字が入っても問題なく表示できること

## wordJoinerを使う

https://developer.apple.com/documentation/naturallanguage/nltag/wordjoiner

そこで今回は、wordJoinerというものを使います。

単語結合子は、Unicodeの制御文字の一つです。

単語の途中など改行してほしくない箇所に単語結合子を入れることで、その場所では改行されなくなります。

```
イメージ: let string = "ボ" + "\u{2060}" + "ヘ" + "\u{2060}" + "ミ" ...
```

## 実装(after)

今回は、stringの拡張として、メソッド化しました。
`characters.joined(separator: wordJoiner)`で全ての文字の間にwordJoinerを追加しています。

```swift
private extension String {
    // 全ての単語の間に Unicode WORD JOINER を挿入する
    func insertWordJoiners() -> String {
        let wordJoiner = "\u{2060}"
        let characters = self.map { String($0) }
        let modifiedString = characters.joined(separator: wordJoiner)
        return modifiedString
    }
}
```

```swift
struct WordJoinerSampleView: View {
    var body: some View {
        ZStack {
            RoundedRectangle(cornerRadius: 10)
                .foregroundStyle(Color.gray)

            Text("ボヘミアン・ラプソデ".insertWordJoiners())
        }
        .frame(width: 96, height: 96)
    }
}

#Preview {
    WordJoinerSampleView()
}
```

## 結果

無事に左詰めで改行されました。

![スクリーンショット 2024-05-01 18.49.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3368292/1551a684-9609-2fc2-154f-4073b17f9b3e.png)


# おわりに

他により良い方法などがあればコメントいただけると幸いです。
エンジニアに必要な「Web技術」を学ぶための書籍ロードマップ

## はじめに

◆この記事は何？
「Web技術を学ぶための書籍」を紹介する記事

◆対象は？
Web技術/Webアプリケーション開発を学びたいエンジニア

◆この記事のねらい
Web技術を学ぶときのロードマップになれば幸いです

## 先に結論

![web.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/280b380f-96d6-26f0-c4ef-3787e7ac9dac.png)

## ①「イラスト図解式 この一冊で全部わかるWeb技術の基本」

[「イラスト図解式 この一冊で全部わかるWeb技術の基本」](https://amzn.asia/d/d5UPLVR)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/899160e5-eaee-648f-4640-de5a5c47c776.jpeg" width=33%>

Web技術の入門としておすすめです。

特に**新卒エンジニア**におすすめできる本です。

◆この本の良いところ
- HTTPの解説が他の入門書よりも詳しい、そしてわかりやすい
- 細かいところまで図解されており、データやコードで理解できる
- ネットワーク、データ形式、アプリ、システム、セキュリティと網羅性が高い

### 他の入門書

[「図解まるわかり Web技術のしくみ」](https://amzn.asia/d/9LNR577)

[「図解即戦力　Web技術がこれ1冊でしっかりわかる教科書」](https://amzn.asia/d/hfmU9jD)

## ②「プロになるためのWeb技術入門」

[「プロになるためのWeb技術入門」](https://amzn.asia/d/6UNVPIL)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/edc94dd1-2acc-3a6d-ece7-e7c055e805d0.jpeg" width=33%>

Webアプリケーション開発に関わる人はもちろん、全てのエンジニアにおすすめできる本です。

「はじめに」の内容が素晴らしいです。

> 開発現場の新人教育では、即戦力として使えるようにフレームワークの使い方など表面的な部分だけを教え込んで、新人を現場に投入せざるを得ない状況が続いています。しかし、根本の仕組みを理解していなければ、問題が発生した時にその原因を突き止めて解決することはできませんし、既存技術の問題点を捉えて新しい技術を生み出していくこともできません。

> 本書は、何年先も通じるWebアプリケーションの基礎技術を、1冊で手軽に楽しく身につけられるようにすることを目標に執筆しました。

この本が書かれたのは2010年です。いまだに読まれ続けていています。

本書に書かれているように、「何年先も通じるWebアプリケーションの基礎技術」を学べる良書です。

## ③「Webを支える技術」

[「Webを支える技術」](https://amzn.asia/d/4Hw2xqg)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/091642fe-9c4a-8a85-401d-1e4b669988f6.jpeg" width=33%>

Web技術の知識を仕上げるための1冊です。

「**エンジニアが読んでおきたい1冊**」になります。

「はじめに」では、

> 本書の対象読者は、規模の大小に関わらずWeb技術を使ったシステムを開発した経験のある人です

とありますが、HTTPをはじめ、Webの仕様や設計について知っておいて損はありません。

もし難しく感じるなら、入門書に戻ると良いと思います。

◆この本の良いところ
- 仕様の解説がわかりやすい
- Webサービスの設計指針が学べる
- Webについて解像度が上がる

## ④「体系的に学ぶ 安全なWebアプリケーションの作り方」

[「体系的に学ぶ 安全なWebアプリケーションの作り方」](https://amzn.asia/d/0Oaxznd)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/616496/dc22f5d6-84e8-bb3e-b0e3-2d594a586953.jpeg" width=33%>

**Webアプリ開発に関わる前**に読んでおきたい1冊です。
セキュリティの対策は早い方が良いためです。

◆この本の良いところ
- 脆弱性とその対策のサンプルが豊富
- ログ設計など、セキュリティに限らず「良いWebアプリをつくるため」の一助となる

### 他の実践的な書籍

[「作りながら学ぶ Webシステムの教科書」](https://amzn.asia/d/g6CO5Rn)

Webサーバーに関わる方にオススメです。
理論に関する説明が少ないので、入門を終えた方向きです。

[「実装で学ぶフルスタックWeb開発」](https://amzn.asia/d/dxRMERx)

フルスタックを目指す方にとって、目次や扱っている話題が参考になりうる書籍です。
より深く学んでいくためには他の書籍も参考にする必要があります。

## おわりに

この記事では、Web技術を学ぶための書籍を紹介しました。

Web技術を学んでいくときの参考になれば幸いです。

それでは。
ChatGPT API を利用したX(Twitter)のツイート自動化【Make利用】


## TL,DR
- Chat GPT で生成したツイートを自動投稿する仕組みを作った
- Makeを使用して定期実行する想定
- 今回プロンプトは適当。今後の課題。


## X Developers ConsoleでClientIDとClientSecretを取得

X Developers Console（https://developer.twitter.com/）
に登録してから、User authentication settingsに行ってClientIDとClientSecretを取得する。

（色々はしょってます、詳細はこちらを参考にしてください）

https://qiita.com/neru-dev/items/857cc27fd69411496388

App permissionsはRead and Writeを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/4ec534e1-194c-3714-8931-e42618d947c9.png)


App infoのコールバックURIの設定値は以下を参照しました。
https://www.make.com/en/help/apps/marketing/twitter


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/ec4fea36-35be-6e1f-a5cc-58e4a46ac6ea.png)

ClientIDとClientSecretをメモ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/8dedca2f-7538-8419-e1b3-2971d93bc8a6.png)



## MakeでOpenAIとX(Twitter)を繋ぐ

### まずはOpenAIのAppを追加
プロンプトは適当に作ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/78a48a29-149d-226d-d4e5-5741275de008.png)


### そして、Xを繋ぐ
ClientIDとClientSecretを設定して、
TextContentには、OpenAIの出力のResultをマッピングする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/c0e4bfb4-78e9-fcb4-b33c-135aef5a0942.png)

### 全体はこんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/b9c3c0db-bf6d-5eea-408d-3d670aee7878.png)

## 実行してみた
左下のRun Onceボタンを押して実行してみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/5b43310f-dee5-3c72-5476-df3a06bdd2d2.png)


無事ツイート成功！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2526943/5bd1de77-f5e1-61e8-5a17-ef4256db9e78.png)


## 感想
- プロンプトさえ頑張ればツイートの自動化は簡単にできそう
- Makeの無料枠は月1000回実行、TwitterAPIも月間ツイート投稿1,500件（1日のAPI経由投稿数の上限は50件）なので、１日１回程度なら余裕