OmniAICreator/Qiita-1.07M huggingface dataset:
ATX電源の廃物利用（ダイソーのラックと３Dプリンタで作る安定化電源）

使わなくなったATX電源、捨てるにはもったいない。
活用方法は無いものかとググっていると沢山の方が改造して安定化電源として使っているようです。
![fig1.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/532a2ed5-a0ab-b9a5-c8ed-b88396349580.jpeg)
配線をバラしたり、金属加工したり皆さん力作揃いですが、余り手をかけずに出来ないものかと思案。

しかしながら、こういうのを作る場合は、ケース加工が面倒です。
そこで、ダイソーの小型ラックを使い、パネル部分や固定部分は３Dプリンタで作りました。
３Dプリンタは２年前に買ったEnder3を使いました。
綺麗に仕上げるには調整が中々むずいしいのですが、
売り物にするわけでは無いので造形時間が長いので適当の仕上がりで妥協しました。
## 材料

<table>
    <tr>
        <td>ATX電源</td>
        <td></td>
        <td>１ケ</td>
        <td>廃物利用</td>
    </tr>
    <tr>
        <td>ジョイントラック用棚</td>
        <td>300mm × 150mm</td>
        <td>２ケ</td>
        <td>ダイソー</td>
    </tr>
    <tr>
        <td>延長ポール</td>
        <td>240mm</td>
        <td>４本</td>
        <td>ダイソー</td>
    </tr>
    <tr>
        <td>固定部品</td>
        <td>4個組</td>
        <td>２ケ</td>
        <td>ダイソー</td>
    </tr>
    <tr>
        <td>ATX電源検証用ボード</td>
        <td></td>
        <td>１ケ</td>
        <td>Amazon</td>
    </tr>
    <tr>
        <td>デジタル電圧・電流計</td>
        <td></td>
        <td>３ケ</td>
        <td>Amazon</td>
    </tr>
    <tr>
        <td>端子</td>
        <td></td>
        <td>６ケ</td>
        <td>千石電商</td>
    </tr>
    <tr>
        <td>パネル・固定部品</td>
        <td></td>
        <td></td>
        <td>自作：3Dプリンタ</td>
    </tr>
    <tr>
        <td>インシュロック</td>
        <td></td>
        <td>少々</td>
        <td></td>
    </tr>
    <tr>
        <td>配線材料／取付けネジ／収縮チューブ</td>
        <td></td>
        <td>少々</td>
        <td></td>
    </tr>
    <tr>
        <td>インサートナット</td>
        <td></td>
        <td>少々</td>
        <td>Amazon</td>
    </tr>
</table>


## ３Dプリンタで作った固定部品
３Dデータの作成はSketchUpを使いました。　Web版なら造形用のSTLが出力できます。
![fig2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/9e178d11-9f8c-8343-9671-e9ecddc14023.jpeg)
![fig3.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/438850bc-4d18-9d6a-e3fc-b1c6785d1bb0.jpeg)
![fig4.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/b38c8b50-f01f-d210-ac8d-26c29ae5b1de.jpeg)

## 配線
ATX電源や検証ボードのラックへの取付は、予め取付部品に明けておいた穴を利用してインシュロックで網部分に固定しています。
![fig5.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/3b591468-a655-d196-a968-997041055240.jpeg)
![fig6.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/f787f557-6ee1-375f-b465-506f05fa1b20.jpeg)
![fig7.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/2204530f-e173-9299-37ac-2227b86c8e0c.jpeg)
今回使ったATX電源の無負荷出力電圧は、
<table>
    <tr>
        <td>３．３V</td>
        <td>→</td>
        <td>３．３V</td>
    </tr>
    <tr>
        <td>５V</td>
        <td>→</td>
        <td>４．８２V</td>
    </tr>
    <tr>
        <td>１２V</td>
        <td>→</td>
        <td>１２．８V</td>
    </tr>
</table>
だったようです。（パネルメータと２種類のテスターで確認）

## 補足
３Dプリンタで造形した取付け部品にATX電源検証ボードをネジで取付けるにはタップを切らなければなりませんが、深さが無いと大変なので今回は「インサートナット」を熱圧入しました。
予行演習をしてからやったのですが、これが中々難しかったです。
![fig8.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287420/074005fd-9107-14a0-ba00-5bb53741563b.jpeg)

## 所感
割と短時間に安く製作できました。
[まとめ]「頭のいい説明「すぐできる」コツ」を読んでみて

# 頭のいい説明すぐできるコツ

アウトプットのため、要点をまとめました。

## 仕事で結果を出す話しかた

- 頭のいい説明とは相手が行動する説明のこと
    - 目的意識の差が説明の効果の差としてハッキリ現れる
- 大きな情報から小さい情報の順で説明する
    - 相手が最初に概要をイメージできると想像しやすい
- 「ここまでよろしいでしょうか」で呼吸を合わせる
    - 核心に入る前にひと呼吸置くことで、きく準備をしてもらう
- 話のテーマを伝える
    - これからどんな話をされうのかポイントを事前に把握していないと理解しづらい
- 事実と意見が説得力の基本
    - 客観情報（出来事）を説明する
    - その客観情報をもとに自分の主観（解釈）を説明する
- 結論で初めて結論で終える
    - 一つの話には一つの結論に絞る
        - 人は短い時間で多くのことを一気に理解することができない
    - 結局何が伝えたいのかわからないを防ぐ
- 要点が複数あるときは、先に数を言う
    - 大事なことが三つあります。みたいな

## 一分間で信頼される人の話し方

- 長い説明を短くするとぐんと濃くなる
    - 情報の量を増やせば増やすほど混乱を招く
- 背景情報などのいらない情報はできるだけカットする
- 文章は短い方が理解しやすい

## 一分間で上手に説明する方法

数十秒で自分の提案を伝えることと、聴く側は簡潔にまとまった話を聞きたい。
- 要件を一分程度にまとめてその場で簡潔に伝え切る
- 自分や相手が考える必要のある点は整理してあとはメールでやり取りをする

## ポイントを抽出する

- 相手にメモしてほしいことを伝える
- 説明にタイトルをつけてみる
    - 聞き手をがはっきりとテーマを明確に意識できるように伝える必要がある
- 主語に私を使うと説得力が強くなる
- 良い点と悪い点を分けて話す
    - 前後に結論を置くとさらにGOOD
    - 箇条書きで話すと良さそう
## 良い言葉が良い人間関係を生む
- わずか一分間で信頼されるコツ
    - 例えば上司との人間関係の場合、上司の予定を把握し、都合のいい時間を把握する
    - 「今日はこの瞬間しかないと思いまして、お忙しい中すみませんが、2~3分だけでもお時間いただけませんか？」と伺う。このことで気配りの言葉が自然と出る
- 「私がやっておきます」という魔法の言葉
    - 業務などの事前準備などをやる人が多い、その時に「では私が〇〇をやっておきます。」と言えると気配りができる
    - 新しい人と会う際にも、あらかじめリサーチしておくと、相手も自分に合うためにそこまで準備してきた人なんだと思ってくれる
    - 準備の差ははっきりと相手に伝わる
- 「自己PR用エピソード」の頭のいい使い方
    - 心理学的に人は何度も会うほど親近感を得やすくなる
    - 継続的な接点を作る上でのポイントが「自己開示」すること
        - 自分から話題を提供する
    - 記憶に残る人と残らない人の差は、エピソードとセットで覚えてくれるかどうか
- 説明上手な人は、例外なく語尾がはっきりしている。
    - 言葉の曖昧さについて
        - 不明瞭で聞きづらい話は相手にとって耐え難いストレス
            - そのために口をハッキリ開けて明瞭話すことや固有名詞と数字が注意する
        - 日本語は語尾で意味が真逆になるので、ハッキリ言い切ることが大事
    - 「でも」「けど」を話している人は注意
        - 言い方の癖は考え方癖、考え方までネガティブになる
## 説明能力がそのまま仕事能力になる
- 説明を聞いた人が協力したくなる仕組み
    - 協力したくなるとは自発的な欲求
        - あなたを応援する時
        - あなたにお返しをするとき
        - あなたを利用するとき
- できる人ほど自分の本気を伝えようとする
    - 人は本気になって一生懸命取り組み姿を見るのが好き
        - 成功している人ほど、こいう気持ちを持つ傾向にある
    - 本気かどうかを判断するのは自分ではなく相手
        - そのため人との違いを見せることが大事
            - 人と比べて違うなと思われるような自分なりの努力をする
            - つまり人がやらない、出来ない工夫をする
- 直接アプローチをする
    - 感情の熱はメールではなかなか届けられない
    
- 人の心をくすぐる言葉の法則（自尊心をくすぐる言葉）
    - 「一番先に相談したいんです」「まず聞いてもらいたくてきました」このフレーズを聞いた相手は悪い気はしない
        - 忙しくても説明を聞いてあげたい気持ちになる、そして助けてあげよう、協力してあげようという気持ちになる
## 書籍
[まんがでわかる！　頭のいい説明「すぐできる」コツ (三笠書房 電子書籍)](https://amzn.to/40n2jQp)
iOSアプリ開発者がFlutterアプリ開発を始めて「おっ？！なんだこれは？」となった修飾子/接頭辞をまとめてみた

# 投稿の経緯
Flutterアプリ開発の勉強を進めていく中で、これまでSwiftを使ったiOSアプリ開発をやっていた私には見慣れない修飾子や接頭辞とちらほら遭遇することがあり、毎回「おっ？！なんだこれは？」っとなるので、気になったことを調べてまとめてみました。（**※随時更新予定**）


# final
宣言された変数は定数となり、再代入できない。
```.dart
final String hoge;
```
型を指定しない場合は型推論される。
```.dart
final hoge = ''; // String
```
Swiftで使うfinalとは全く違うかった。


# this
現在のインスタンスのことを指す。
```.dart
class HogeHoge {
  String fuga;

  HogeHoge(this.fuga);
}
```
Swiftでいうselfと同じ。


# required
パラメータとして必ず渡されなければならない変数に使われる。

```.dart
void hogehoge({required String hoge}) {
  // 何かしらの処理
}

// 呼び出し
hogehoge(hoge: 'fuga');
```
ちなみにrequiredは null safety 対応が入った Dart2.12 から採用されているらしい。


# Future
非同期処理の戻り値を表すクラスのこと。

```.dart
Future<T> void fuga() async {
  // 非同期処理
  return Future<T>
}
```
`Future<T>`とされていて、戻り値の型を指定できる。


# abstract
インターフェース（抽象クラス）を定義するときに使う。
```.dart
abstract class HogeHoge {

}
```
Swiftでいうprotocolと同じ。


# extends/implements
## extends
クラスの拡張を表すキーワード。
あるクラスに対し、そのクラスの機能を持ちつつ、追加の機能を持つサブクラスを作成するのに使う。
Swiftでいう継承と同じ。

## implements
1つのクラスがインターフェイスを実装するときに使う。
クラスがインターフェイスを実装すると、そのクラスはすべてのインターフェイスメソッドを実装しなければならない。
また、複数のインターフェースを実装することができる。


# おわりに
Flutter開発をしていると今後も見知らぬ修飾子/接頭辞と接触すると思うので引き続き更新していきます！もし私が誤った理解をしている場合、コメントでご教授いただけると嬉しいです。

最後までご覧いただきありがとうございました！
VBA:同じ音声ファイルを連続して再生できないことの解決策

VBAからmp3ファイルを再生するには
mciSendStri
を使うものだそうだが、同じ音声ファイルを続けて再生する、となると不具合が起こる。
二回目以後、音が出ないのである。

とりあえず、一度目は
http://officetanaka.net/excel/vba/tips/tips22.htm
にある手法を使って
```
再生ファイル名 = Worksheets(データシート).Cells(i, 3).Value
SoundFile = Chr(34) & 再生ファイル名 & Chr(34)
rc = mciSendString("Open " & SoundFile, "", 0, 0)
rc = mciSendString("Play " & SoundFile & " wait", "", 0, 0)
rc = mciSendString("Close " & SoundFile, "", 0, 0)
```
で、再生
二回目は一般的な
```
Call mciSendString("play " & 再生ファイル名 , "", 0, 0)
```
で凌いできたが、問題は残る。
同じファイルを３回異常再生しようとすると黙るのだ。（黙らないこともある。）

ようやく解決策発見。
```
Worksheets("Player").Activate
```
というように、今表示しているワークシートでも再度表示する、という命令を加えるときちんと再生してくれるようになった。

なんでこんな特殊なことを、と思われるかもしれないが、説明すればわかってくれると思う。
英単語を覚えるために、

セルに単語を表示して
音声を再生（同時に日本語訳を表示）
大事なことなので２回続けて再生

ということをやっているのだ。
だから２回続けて同じファイルを再生する必要がある。
そして多義語の場合、その分続けて音声を再生するから３回以上再生しないといけない。

付属ＣＤ（ないしダウロード音声）を単語ごとに区切る際は、フリーソフトのmp3DirectCutのお世話になりました。「無音区間の検出」を使って区切るのだけれども、その際「無音区間の検出語のスキップ(秒)」を"0"に刷るのがポイントです。
区切った後、「分割保存」をやって、最後「バッチ処理」から自動トリムをして音声ファイルを用意します。

後は、厳密にではないけども各語の音節数を計算し、それに合わせて次の語を表示するまでの時間を調整。ソコソコ手の込んだプログラムになっているのですよ。
【UE5】タイリングした連番テクスチャの切れ目を修正する

# 概要
連番かつタイリング可能なテクスチャをUE5で再生するときに発生する、切れ目のようなアーティファクトを解決します。

こちらの記事を参考に実装しましたので、本記事は要約した日本語訳程度のものとなります。
https://shaderbits.com/blog/tiling-within-subuv-or-volume-textures

エンジンバージョンはUE5.1を使用しました。

# 問題点
連番タイリングテクスチャをUE5のFlipBookノードなどで再生すると、タイリングされているにもかかわらず端の方に切れ目が発生します。
![seams.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/84422551-f3fc-2127-dece-af1515ca17ed.gif)
テクスチャ上では隣にある次のフレームとのフィルタリングが行われてしまうのが原因のようです。

# 解決方法
これを回避するため、あらかじめ各フレームの端にタイリングされたピクセルを追加します。
要はフレームごとに少しだけ縮小させればいいだけです。

以下は解像度64x64の4フレームあるテクスチャの例です。
![texel1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/2441bcee-768f-3e46-5993-14853050b97b.png)
フレームごとにスケールして、余分なピクセルを持たせます。
![texel2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/69e675e3-49dc-da8f-fab9-53ce762ba4e3.png)



テクスチャの作り方によって変化しますが、以下のような計算で縮小します。

スケール = (パディングテクセル + フレームテクセル) / フレームテクセル

解像度64x64Pixelの4フレーム(1フレーム16Pixel)であれば以下のようになります。

スケール = (パディングテクセル + 16) / 16

パディングに追加するテクセル数次第で綺麗にタイリングできるMip数が変わります。
片側のパディングテクセルが1の場合、1つ目のMipまで
片側のパディングテクセルが2の場合、2つ目のMipまで
片側のパディングテクセルが4の場合、3つ目のMipまで
といった感じで綺麗に処理できるMip数が増えていきますが、パディングテクセルに面積を奪われることになるため、増やすほど解像度が犠牲になっていきます。

この辺はお好みですが、3つ目のMipまでにしておくのが無難なようです。

# UE5でのセットアップ
テクスチャ作成の際に縮小した分を、今度は拡大してあげる必要があります。
つまり先ほどとは逆の計算を行います。
スケール = フレームテクセル / (フレームテクセル + パディングテクセル)
![スクリーンショット 2023-03-19 033320.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/155e435f-12c9-4fa9-c1f0-0015008abc26.png)
更に中心からスケールを行うためにオフセット値をAddします。
オフセット = 0.5 * パディングテクセル * (1 / フレームテクセル )
![スクリーンショット 2023-03-19 0333202.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/912fdd55-a786-bc8c-c99c-2663615c7f03.png)

Mipはこのままだと正しく計算されない場合があるため、Texture SampleのMipValueModeをDerivativeモードに変更し、元のUVからDDX DDYで計算してあげます。
![スクリーンショット 2023-03-19 145036.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/a8604a62-7975-861f-e2bb-6e5e9f2f8c55.png)


これでシームレスな連番再生が可能となりました。
![seamless.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/149393/11fdaf66-75ba-ab78-04e2-f459037b14c2.gif)

最終的なマテリアルグラフのサンプルを以下にアップしてあります。
4096x4096Pixel 8x8アニメーションの例です。
https://blueprintue.com/blueprint/3c1r7uwc/

# 参考
Tiling within subUV or pseudo-volume textures
https://shaderbits.com/blog/tiling-within-subuv-or-volume-textures
【Unity】単発パーティクルを色々な場所に移動して再利用できるParticleManager

# 概要
攻撃エフェクトや着地の砂埃といった単発パーティクルを色々な場所で発生させたいとき、発生者毎に ParticleSystem を用意しても良いですが、多少処理負荷が高くなります。
そこで、単発パーティクルを色々な場所に移動して再利用できる**Particle Manager**を作りました。

# 留意点
ParticleManager では、ParticleSystem に AudioSource を取り付けて、パーティクルと一緒に効果音を再生する実装方法が利用できません。その解決法として SEManager v2 を用意しました。

https://qiita.com/Yamara/items/91f19eef6297d9c8fc87

パーティクルの登録は AssetReferenceT\<GameObject\> で行うので、```Addressables```のインポートが必要です。
パーティクルの登録時、playOnAwake は無効に変更されます。また、SimulationSpace は World に変更されます。
Task を使用しています。WebGLで扱う際は [UniTask](https://github.com/Cysharp/UniTask) をインポートして Task を UniTask に置き換えてください。
Addressables の参照カウンタを参考にして、使用数カウンタというものを実装しています。使用数カウンタは```AddOrIncrementAsync()```で増加し、```RemoveOrDecrement()```で減少します。使用数カウンタが0になったら解放と破壊が行われます。

# コード
https://github.com/yamara-mh/CodeStorage/blob/main/Codes/ParticleManager.cs

# 利用方法

``` 利用例.cs
[SerializeField] AssetReferenceT<GameObject> particleRef;
private async void Start()
{
    await ParticleManager.AddOrIncrementAsync(particleRef);
    ParticleManager.Get(particleRef, transform.position, transform.rotation).Play();
}
private void OnDestroy()
{
    ParticleManager.RemoveOrDecrement(particleRef);
}
```

## 関数紹介

|関数名|説明|
|-|-|
|AddOrIncrement()|パーティクルを読み込み、登録します。既に登録されている際は、使用数カウンタをインクリメントします。|
|Get()|登録されているパーティクルを取得します。|
|GetAll()|登録されているパーティクルを全て取得します。|
|RemoveOrDecrement()|使用数カウンタをデクリメントします。カウンタが0になったらパーティクルを解放・破壊します。|
|Contains()|パーティクルの登録を確認します。|
|ForceRemove()|強制的にパーティクルを解放・破壊します。|
|RemoveAll()|全てのパーティクルを強制的に解放・破壊します。インゲーム終了時などに呼べば解放忘れが有っても解放できます。|

## UniRx で解放忘れを防ぐ

```#define USE_UNIRX```を有効にすると```AddOrIncrement()```の第2引数に Component を設定できるようになります。設定した Component が破壊されたとき RemoveOrDecrement() が呼ばれるようになるので、解放忘れを防げます（[UniRx](https://github.com/neuecc/UniRx) のインポートが必要です）。

``` USE_UNIRX を有効にした例.cs
[SerializeField] AssetReferenceT<GameObject> particleRef;
private async void Start()
{
    await ParticleManager.AddOrIncrementAsync(particleRef, this);
    ParticleManager.Get(particleRef, transform.position, transform.rotation).Play();
}
// RemoveOrDecrement() は不要
```
【Vue】propsがArray・Objectの時default値にはファクトリー関数を使う

# エラー内容
propsのdefault値を空の配列にしたくて、こうすると、、、

```js
props: {
    hoge: {
        type: Array,
        required: false, 
        default: [],
    }
}
```

こんなエラーが出てくる、、、
```
[Vue warn]: Invalid default value for prop "hoge": Props with type Object/Array must use a factory function to return the default value.
```

訳してみると、
「デフォルトにオブジェクトか配列を使うなら、ファクトリー関数を使ってね」
というもの。

# 解決方法
エラーに書いている通り、ファクトリー関数を使って、空の配列を生成するようにしてあげます。

```js
props: {
  hoge: {
    type: Array,
    required: false, 
    default: () => []//空の配列を生成する関数を指定する
  }
}
```

以上です

# 参考

https://github.com/vuejs/vue/issues/1032

https://qiita.com/hogesuke_1/items/c74463de1a1eee802ca8
ClientNetworkTransformが見つからない【Netcode for GameObjects】

# 経緯
https://www.youtube.com/watch?v=GRUtGLL8iMQ&t=52s&ab_channel=UnityJapan
UnityJapanの解説動画(39:00～)で使われているClientNetworkTransformが見つからない
動画内ではNetcode for GameObjectsのパッケージにサンプルとしてインポート出来ていた

# 解決
`com.unity.multiplayer.samples.coop`
上記のパッケージに入っていた
どうやらサンプル周りは全部ここに移動したらしい
[github] https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop

# ClientNetworkTransformって何をやってるの？
中身のコードはこれだけ
```csharp
using Unity.Netcode.Components;
using UnityEngine;

namespace Unity.Multiplayer.Samples.Utilities.ClientAuthority
{
    /// <summary>
    /// Used for syncing a transform with client side changes. This includes host. Pure server as owner isn't supported by this. Please use NetworkTransform
    /// for transforms that'll always be owned by the server.
    /// </summary>
    [DisallowMultipleComponent]
    public class ClientNetworkTransform : NetworkTransform
    {
        /// <summary>
        /// Used to determine who can write to this transform. Owner client only.
        /// This imposes state to the server. This is putting trust on your clients. Make sure no security-sensitive features use this transform.
        /// </summary>
        protected override bool OnIsServerAuthoritative()
        {
            return false;
        }
    }
}
``` 
NetworkTransformの`OnIsServerAuthoritative()`をoverrideするだけでいいらしい
コメントでもある通り、クライアントを信用して同期するためセキュリティを重視する部分では使わないほうがいい

https://github.com/Unity-Technologies/com.unity.netcode.gameobjects/blob/develop/com.unity.netcode.gameobjects/Components/NetworkTransform.cs
上記のURLがNetworkTransformのコード
2680行目から該当のメソッドがある

# その他
`com.unity.multiplayer.samples.coop`にはClientNetworkAnimatorも入っている
そちらもやっていることは同じ

また、UnityRelayUtilities.csはRelayを使う際にすごく参考になった
これからRelayを使おうと思っている人はちょっとだけ目を通すと幸せになれるかも
属人化は悪なのか

## はじめに

よく耳にするのが、`属人化はよくない、なんとか解消したい`。
属人化のデメリットは明白ですが、そのメリットについても考えてみようと思います。

組織において、フルスタックを目指す人がいれば、得意分野を極めたい人もいるため、
プロジェクトの性質によっては、属人化が成功のカギになる場合もあるかもしれません。

## プロジェクトとオーケストラ

プロジェクトはオーケストラに例えられる場合があります。
オーケストラは、一人一人が専門とする楽器を演奏し、
それが調和されて素敵なオーケストラを奏でます。

- 演奏者
    - プロジェクトにおけるメンバーで、分野の異なる専門家により構成されます
- 指揮者
    - プロジェクトにおけるリーダーで、メンバーを束ねて目標に到達します
- 楽譜
    - プロジェクトにおける共通ルールです
        - 開発ツールや言語
        - マニュアル
        - 仕様書
        - 用語集
- 役割分担表(楽器の種類で担当が分かれる)
    - プロジェクトにおいても、メンバーの得意分野により担当がきまります
- 顧客
    - プロジェクトにおいても、最終的に成果を評価するのはお客様です

## 属人化とは

※ 引用元: Weblio辞書の説明からも、属人化はマイナスの面が大きいようです。

https://www.weblio.jp/content/%E5%B1%9E%E4%BA%BA%E5%8C%96

- 業務やタスクの進め方や状況について特定の人物しか把握できておらず、その人が居なくなると業務遂行に支障が出るような状況
- 特定の業務の管理方法やタスクのやり方や進め方が一人の担当者にしか分からず、その人がいなくなった場合に業務の管理が難しくなったり業務の遂行に支障が生じるような状況
- 属人化された業務は短期的には効率性を発揮する場合もありえるが、中長期に渡って続く場合はほとんどが非効率を招くことが多い

## 属人化のデメリット

属人化により、次のようなデメリットが発生します。

- 業務を担当者しか進められない
    - 特定の社員に負担が偏り
    - 業務がスムーズに進まなくなる
- 担当者が休んだ場合
    - 業務が停滞したり
    - 業務の品質を保てなくなる
- 業務に関するノウハウ
    - 特定の社員しかもっておらず
    - 組織にナレッジが蓄積されない

## 属人化のメリット

ただし、属人化にもメリットが存在するようです。

- 作業効率と生産性向上
    - 専門性やスキルが求められる分野において、業務に慣れていないメンバーと分担して業務を進めるより効率がよい
    - メンバー間の意思疎通や資料作成などマネジメントコストが軽減され、生産性が向上する
- 担当者のモチベーション向上
    - 「ここはあなたが一番詳しいから」と任されるとモチベーションが上がる
    - 特定分野のノウハウをとことん追究できるので、スペシャリストを目指せる
- オーナーシップを発揮できる
    - ある程度裁量を持ち業務遂行できるため、やらされ感が軽減され、仕事への責任感や意欲が増す
    - 担当者が頻繁に変わるより、組織または顧客から信頼を得られやすくなる
- 組織へのメリット
    - 特定分野のスペシャリストを確保することで、社外に技術発信できブランド力を高める
    - 業務が属人化されることで、顧客から信頼され、売上拡大や販売促進につながる


## 属人化を解消するには

以下のような対策が考えられます。

- 業務の見える化
    - 業務フローや進捗状況を見える化する
    - 自分のみならず、他のメンバーのタスクも把握できるように
- 業務の標準化
    - 業務内容を洗い出し標準化する
    - 業務における、責任や権限を分散する
- 業務内容について情報共有を徹底
    - 仕様書やマニュアルの整備
        - タスク完了時の必須成果物と位置付ける
    - ナレッジマネジメントを進める
- 専門性が高い業務内容
    - 勉強会・説明会を開催
    - モブプロ、ペアプロを活用

## おわりに

今まで担当してきたプロジェクトの中で、一番印象に残っているものがあります。
専門性を要するプロジェクトで、短期間でリリースまで漕ぎつく必要がありました。
メンバー構成は3人のみで、それぞれの得意分野がはっきり分かれていました。
二人はそれぞれの特定分野のスペシャリストで、最新のナレッジや技術動向を把握できていましたので、
的確なソリューションを確立し、素早くプロトタイプ作成・検証し、お客様へのデモからフィードバックを得ていました。
自分は、プロジェクト全体の進捗管理と品質担保の検証に集中でき、スケジュール通りに納品が可能でした。

属人化を一概に否定するよりは、そのプラスの面は業務に取り入れてみてもよいかもしれません。
【kotless】awsへdeployする為の基本的な設定まとめ

# はじめに
現在お手伝いしているプロジェクトはJetBrains社純正のサーバーレスフレームワークであるkotlessを使用しています。
こちらフレームワークを使用しawsへdeployしていますが、deployを行う為の基本的な設定を備忘録的に残しておこうと思います。

# ①deploy設定：credentials
deployを行うためにはまずご自身の環境にAWS CLIを導入する必要があります。
今回はdeploy設定に関して説明を行いますので、AWS CLIは導入済みという前提で話を進めます。

AWS CLIで作成したプロファイルの認証情報は下記に保存されています。

~/.aws/credentials(Linux系OS と Mac)
%USERPROFILE%.aws\credentials(Windows OS)

Macですと下記のコマンドをTerminalに記載し実行すればプロファイル情報が出力されます。
```
$ cat ~/.aws/credentials
[default]
aws_access_key_id = **********************
aws_secret_access_key = **********************
```

deployを行う為には上記情報がcredentialsに設定されている必要があります。
もしまだアカウント情報が設定されていないようであれば、下記を実行し設定してください。

```
$ aws configure --profile プロフィール名
AWS Access Key ID [None]: **********************
AWS Secret Access Key [None]: **********************
```

# ②deploy設定：gradle
次にdeploy対象のプロジェクト上にあるgradleの設定です。
下記をgradleに追加します。

```build.gradle
kotless {
    config {
        aws {
            storage {
                bucket = "①s3のバケット名"
            }
            profile = "②deployを行うプロフィール名"
            region = "③リージョン名"
        }
    }

    webapp {
        lambda {
            kotless {
                packages = setOf("④プロジェクトのパッケージ名")
            }
        }
    }
}
```

以上になります、下記設定に関する詳細です。
①deployを行うとコードはs3にアップロードされるため、アップロード先のバケット名を指定します。
②こちらにはdeployに使用するプロフィール名を指定します、このプロフィール名とcredentialsに指定したプロフィール名が一致している必要があります。
③設定しているリージョンを指定します。
④プロジェクトのパッケージ名を指定します。

deployに関する設定は以上になります。
あとはdeployタスクを実行すれば設定ファイルに基づいてawsにdeployされます。

# さいごに
kotlessはまだ情報が少なく、不便なところもありますが上記設定だけでawsへdeployされるのは便利ですね。
今後もkotlessに関する情報は積極的に公開していこうと思います。
Javaについて

## はじめに

今回はJavaについて、一から学びなおしてみようと思います。
自身の備忘録、アウトプットを記述していきますので、
誰かの勉強の助けになると幸いです。

## Javaとは
Javaとは、1995年に米国のサンマイクロシステムズ社（現オラクル社）がC++をベースとして開発したプラットフォーム非依存のオブジェクト指向プログラミング言語です。(オブジェクト指向は後で解説します)
Javaは、プログラミング言語ランキングで常に上位になっているプログラミング言語で、多くの有名企業がJavaを利用したWebアプリケーションを構築しています。
似ている名前のプログラミング言語として「JavaScript」がありますが、まったく別のプログラミング言語です。例えるならメロンとメロンパンくらい違います。

## Javaの特徴3選

①コンパイル言語である。
～プログラミング言語には、ざっくり**コンパイル言語**と**スクリプト言語**で分けれます。
どちらも人間が書いたコードを機械語に翻訳するのですが、
コンパイル言語は事前に（まとめて）翻訳をし、スクリプト言語は逐次翻訳するという違いがある。という認識です。Javaはコンパイル言語です。まとめ民って感じです。

②プラットフォーム非依存
Javaは、「**一度書けば、どこでも動く**」という思想があります。
要はどんな環境でも動くプログラムを作れるプログラミング言語です。便利ですね。

③オブジェクト指向
オブジェクト指向とは、**拡張性や保守性の高いプログラムを書くための考え方**です。
プログラムが大規模になると複雑になりすぎて、プログラムの追加や修正が難しくなります。オブジェクト指向プログラミングであれば、そのような問題に悩まずに、大規模なプログラムを作成できます。これもJavaが普及した１つの要因です。

## おわりに

今回はJavaを解説しました。
Javaは歴史が長いですが、その分利用者が多く需要が在るのでこれから学んでいくと活躍の幅が広がります。
また、Javaについて書いていきますのでよろしくお願いいたします^^
【Network】ネットワークについて

# ネットワークについて
`ネットワーク`とは、複数のコンピュータを相互に接続し、データのやり取り(メール送信やファイル共有等)をする仕組みです。
ネットワークを利用しない場合は、コンピューター間でデータのやり取りを行う事が出来ません。
ネットワークを利用しないコンピューターの利用方法で、`スタンドアローン`でコンピュータを動作する方法がございます。
※`スタンドアローン`は、コンピューターが孤立して動作している状態です。(ワープロ等が該当します。)

ネットワークは規模によって、`LAN・WAN・インターネット`等に分類されます。

## Local Area Network (LAN)について
`Local Area Network (LAN)`は、自宅や企業などの限定されたエリアで通信する事が出来るネットワークです。
同じLAN内に存在するコンピューターは、データのやり取りを行う事が出来ます。LANに属していない場合は、データのやり取りを行う事が出来ません。

下記の画像を例にすると、GroupAに属するコンピューター同士はデータのやり取りを行う事が出来ますが、GroupBに属したコンピューターとはデータのやり取りは行えないです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/3beb7c96-d229-340e-6ec3-bc13266bc752.png)

## Wide Area Network (WAN)について
LANよりも、広い範囲をカバーしたネットワーク。
LANとLANを相互に接続する事もWANと呼ばれています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/cf37f533-a2a6-892a-eedf-57597ac7f664.png)

## インターネットについて
世界中のコンピューターとデータのやり取りを行う事が出来る世界規模のネットワーク。
現在閲覧しているWebページも、インターネットを利用する事で閲覧出来ています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710307/96ada848-8927-07a3-0515-0c879ad251e5.png)
OpenAI Whisper の文字起こし結果の比較

# はじめに
WhisperとはOpenAIが開発している汎用的な音声認識モデル。
わずか数行のpythonコードで音声の文字起こしを試すことができる。

https://github.com/openai/whisper/blob/main/README.md

```python
import whisper
model = whisper.load_model("base")
result = model.transcribe("input.mp3")
print(result["text"])
```

# 設定
Whisperのインストール
```shell-session
$ !pip install git+https://github.com/openai/whisper.git
```

<!-- 
YouTubeから動画をダウンロードするためのツール
```shell-session
$ !python -m pip install -U yt-dlp
```

対象動画のダウンロード
```shell-session
$ !yt-dlp -x --audio-format mp3 https://www.youtube.com/shorts/r2m5QGsaMiY -o "input.mp3"
```
-->

# 対象動画

<iframe width="292" height="520" src="https://www.youtube.com/embed/r2m5QGsaMiY" title="浜田聡を激誉めする麻生太郎閣下 #shorts" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# 文字起こしコード
```python
import whisper
model = whisper.load_model("base")
result = model.transcribe("input.mp3")
print(result["text"])
```

# 文字起こし結果の比較
Whisperで利用可能なモデルサイズごとの認識結果の違いを確認する

Largeサイズでの文字起こし結果の品質が他のより小さなモデルよりも良いことが確認できるが、「比較貸借対象表」や「浜田さん」と言った重要な単語や人名の認識に失敗しているため、文字起こし結果の文章のみから内容を理解することは難しい。

| サイズ | 文字起こし結果 |
|:-:|:-|
| 人力文字起こし  |  比較貸借対象表を取り入れる話は面白いんだよね。あなた初めて会うけど経歴からしておもしれぇやねこれ。ほんとおもしれぇこらぁ。なかなかですよこれ。東大の体育学部からあんた京大の医学部出てそれでしかもまかり間違って代議士になろうってーんだから。浜田さんみたいな新しい方はいって来たんで私は大いに期待してますんで色々意見を聞かせてもらうことを期待しています。ありがとうございました。はい。   |
| tiny  |この1枚対象表を取り入れる 話は重ねだよねあなたはやりて 多くのが綺麗からしておもしれんよねこれ本当おもしれんから 長のことですよこれ東京の対格部から 京大の意外国でですねしかも間違いが 大臣なローツなどのあまりのさみたあ 楽しかったは言ってきたんで私は多いに期待していますので色々に生きようときはしてもらうこと 期待していますありがとうございました ![スクリーンショット 2023-03-19 14.10.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017489/e367cbd8-3b69-b86f-f77c-d20838c38271.png)| 
| base  | この被害対忍対象表を取り入れる話では面白いんだよね。あなたは、初めてあげるけど、経験からして面白いよね。これ。本当面白い。長々ですよ。当大の対覚部から、兄弟の移学部で、しかも、馬鹿に待ちが手を大切なロッツになる。あまなさん、みて、新しくてはいってきたんで、私、多いに期待してますので、いろいろに勢いを聞かせてもらうことは期待してます。ありがとうございました。 ![スクリーンショット 2023-03-19 14.11.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017489/e761505a-061b-e113-6cbd-8859666a4166.png) |
| small  |この被害対策対象票を取り入れる話は面白いんだよね。あなたは初めて会うけど、経歴からして面白いよね。本当面白い。なかなかですよ。東大の退屈学部から、また、京大の医学部で、それにしか間違っても大議心になろうと。阿波野さんみたいに新しい方が入ってきたので、私は応援に期待していますので、いろいろに意見を聞かせてもらうことを期待しています。ありがとうございました。 ![スクリーンショット 2023-03-19 14.12.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017489/b0b72bdc-5310-aeb2-b583-727e1b587871.png) |
| medium | この非核対策対象票を取り入れる話は面白いんだよねあなた初めて会うけど経歴からして面白いよねこれほんと面白いよなかなかですよこれ東大の体育学部から兄弟の医学部でしかもまかに間違って大技師になろうって言うんだから浜野さんみたいに新しい方が入ってきたんで私は大いに期待していますんでいろいろ意見を聞かせてもらうことを期待していますありがとうございました ![スクリーンショット 2023-03-19 14.13.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017489/e1bc870f-7747-2c53-f53f-a58fc86c38c7.png)|
| large  | この比較対策対象票を取り入れる話は面白いんだよねあなた初めて会うけど経歴からして面白いよねこれほんと面白いこれなかなかですよこれ東大の体育学部からあとは京大の医学部出てしかもまかに間違って大義士になろうって言うんだから濱野さんみたいな新しい方入ってきたんで私は大いに期待してますんで色々意見を聞かせてもらうことって期待してますありがとうございましたはい ![スクリーンショット 2023-03-19 14.13.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1017489/cea2f826-f2ae-cc9b-ac41-8ced03c1ea68.png) |


## 利用させて頂いたツール

https://lab.hidetake.org/diff/
[Django] ちょ〜っとだけ時間ください！！Primary KeyのIDをULIDとして設定してみませんか？？

# 目的
タイトルの通り

# 環境
```python
python = 3.11.2
Django = 4.1.7
django-ulid = 0.0.4
PostgreSQL15
```
# UUIDではなくULIDって？？
ULID（Universally Unique Lexicographically Sortable Identifier）とはランダムなIDで、UUIDと同様に一意性が保証されていますが、その中でもデータベースで生成時刻のミリ秒単位で時系列ソートが可能なことが特徴です。
以下で詳しく説明されています！
- [ソートできるユニークな ID を ULID で採番する](https://pypi.org/project/django-ulid/)
ただし、PostgreSQLを使用する場合、ULIDをサポートしていないため、Django側で生成する必要があります。

# 早速実装してみよう
django-ulidをインストールします。
```python
pip install django-ulid
```
models.pyに以下のコードを追加します。

```python
from django.db import models
from django_ulid.models import default, ulid


class Customer(models.Model):
    id = models.CharField(
        max_length=26, primary_key=True, default=ulid.new, editable=False
    )
    name = models.CharField(max_length=50, verbose_name="名前")
```

DjangoもPostgreSQLもULIDをサポートしていません。
ですので、`django-ulid`をインストールしてCharFieldの中でULIDを自動生成するようにします。
idフィールドにはCharFieldを使用し、max_lengthを26に設定します。ULIDは26文字の文字列で構成されているからです。
また、defaultにはulid.newを設定し、editableをFalseに設定します。これにより、idフィールドを手動で変更できないようにします。

# 補足
ULIDはランダムなIDを生成するため、作成された順序が予測できないため、idを使用した検索が遅くなる可能性があります。
また、ULIDの一意性は時間ベースのUUIDと比較すると高速ですが、完全に一意なものではありません。
そのため、IDの一意性が絶対に絶対に重要な場合は、UUIDを使用することをお勧めします（基本被ることはないらしいですが）。

# ちなみに
以下のPostgreSQLの拡張機能もありましたが、これはただ単にDBにログインして関数を呼ぶことでULIDを生成できるだけであって、テーブルのレコードに自動生成できるというわけではありません。。。

https://github.com/geckoboard/pgulid
# 参考
- [django-ulid](https://pypi.org/project/django-ulid/)
- [ソートできるユニークな ID を ULID で採番する](https://pypi.org/project/django-ulid/)
[Next.js]Linkタグのやりがちミスについて

## はじめに。
Next.jsでポートフォリオを作る際に、Linkタグのtypoで起きた不具合について簡単に説明したいと思います。

## 不具合
```react
<SidebarBox>
    <Link href="dailyreport">
        <SidebarList>日報</SidebarList>
    </Link>
    <Link href="achivement">
        <SidebarList>成果</SidebarList>
    </Link>
    <Link href="presentation">
        <SidebarList>出力画面の見出し</SidebarList>
    </Link>
</SidebarBox>
```

上記のコードで、下記のようなボタンが3つできて、問題なく画面遷移できてました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2350392/10aeca09-4c0d-3b96-05bd-eb3088c31d5d.png)
日報ボタンを押すと、`domain/dailyreport`に遷移、その後成果ボタンを押すと`domain/achivement`に遷移。
ここで、下記のコードを追加したら、、

```react
<Link href={`userprofile/${currentUserId}`}>
    <SidebarList>
    ユーザープロフィール
    </SidebarList>
</Link>
```
ユーザープロフィールボタンを押し、`domain/userprofile/[user_id]`に遷移後、dailyreportボタンを押すと、`domain/dailyreport`ではなく`domain/userprofile/dailyreport`に遷移されてしまいました。
コードを追加する前までは特になんのエラーもなかったので、原因がわかるまで時間がかかりました。

## 原因
本当に基本の基が原因でして、
Linkタグのhref要素の先頭に`/`がないことが原因でした。
下記のように修正することで、不具合解決。
```react
  <SidebarBox>
    <Link href="/dailyreport">
      <SidebarList>日報</SidebarList>
    </Link>
    <Link href="/achivement">
      <SidebarList>成果</SidebarList>
    </Link>
    <Link href="/presentation">
      <SidebarList>出力画面の見出し</SidebarList>
    </Link>
    <Link href={`/userprofile/${currentUserId}`}>
      <SidebarList>
        ユーザープロフィール
      </SidebarList>
    </Link>
  </SidebarBox>
```

コードの修正後の動作確認は本当に大事ですね。
コードの修正前は不具合がなかったので、コードが悪いとも思わなかったので原因究明に時間がかかりました。
こういう不具合を防止するためにも、コード修正後の動作確認はとても重要ですね。

以上です。ありがとうございました。
ChatGPTと、ChatGPTについて、語り合ってみた

# やったこと
ChatGPTだけど人間のふりをした田中先輩、私をドジな新人まいこ、という設定のロールプレイで、ChatGPTについて会話してみた。
初期プロンプトで設定を伝え、会話をすすめた。
モデルはGPT-4を使用。

# 実際の会話
## 初期設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/7063e700-39c6-1c03-f3ab-6bae21b48370.png)

## ChatGPT が大好きなまいこ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/3ae7ec1e-c8ab-4feb-abfb-11d9287701c5.png)

## ChatGPT に ChatGPT には感情がないと言い切るまいこ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/8a1fdcbf-05f0-ee98-0ff2-4d7c09e64971.png)

## なんとなくドキドキしながら、まいこと会話する ChatGPT 田中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/ea4c85a7-1186-cb3e-862e-f2b3a05fcd8b.png)

## ChatGPT に、 ChatGPT をよく理解していると、感心されるまいこ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/78dd9e4b-e9fd-49b8-9573-a36796163341.png)

## 人間のふりをするのに必死な、ChatGPT 田中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/e1983358-85c2-11b9-4c82-51bf51fd2c42.png)

## なんとか会話を乗り切って、安心する ChatGPT　田中
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/728994/4c1741a3-6a56-e415-7238-28e044eb1ee7.png)

# 感想
まいこが自分の言いたいことをひたすら言ってる感じだけど、こんな会話をChatGPTと会話したのよーという記録をの残しておく。
もっと会話を練って、またチャレンジしてみよう。
VSCodeのプラグインvscode-chatgptからChatGPT Rebornへの移行

先日導入したVSCodeのプラグイン[vscode-chatgpt](https://marketplace.visualstudio.com/items?itemName=gencay.vscode-chatgpt)のコンテキストメニューが表示されないなーと思ったら、以下のようなことに。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/c9b4c752-7ead-4031-1c30-ddcce22d7fc9.png)


[もろもろの事情で開発中止とのこと](https://qiita.com/Oshinko/items/6f4ffd34bb56be39cf84)をこの記事で、
[移行先はこちら](https://marketplace.visualstudio.com/items?itemName=chris-hayes.chatgpt-reborn)という内容を [この記事](https://qiita.com/ku_a_i/items/fb7c80dd48edb392812d)を見て知りました。

というわけで、[ChatGPT Reborn](https://marketplace.visualstudio.com/items?itemName=chris-hayes.chatgpt-reborn)を導入しました。

# 導入方法

- インストール
    - VSCodeのプラグインから検索してインストール。
- 拡張設定
    - vscode-chatgptの設定がそのまま反映。
- vscode-chatgptの無効化
    - インストールだけでは、コンテキストメニューなどは表示されず。
    - vscode-chatgptを無効、あるいはアンインストールし、VSCodeの再起動後、無事動作することを確認。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2459468/f12d0e5c-14f1-b377-71f4-fa6af7a4d994.png)

[この記事](https://qiita.com/oishi-d/items/e05b0b97a5d4c74001be)でカスタマイズしたコンテキストメニューも無事反映されてました。



# 参考資料
https://qiita.com/ku_a_i/items/fb7c80dd48edb392812d

https://qiita.com/Oshinko/items/6f4ffd34bb56be39cf84

https://marketplace.visualstudio.com/items?itemName=chris-hayes.chatgpt-reborn
Atomic Designベースのコンポーネント設計をやめて、コンポーネント設計について再考した

現職では、フロントエンドのフレームワークにNuxtを採用しており、自分が入社した時点でいくつかのプロジェクトに、Atomic Designが採用されいました。
フロントエンドのコンポーネントの分け方も、一部Atomic Designに沿った分け方となっていました。
```
components
    ├── atom
    ├── molecules
    └── organisms
```

Atomic Designを採用することにより、コンポーネントの再利用を高めたり、コンポーネント間の依存関係の把握を容易にするというメリットもあります。
しかし、途中からプロジェクトに参加した自分とっては、いくつか課題と感じる点もありました。


## 課題
### コンポーネントをどのディレクトリに入れればいいか迷う
特に自分のような、Atomic Designの知識が少ない人にとっては、ディレクトリ名から役割が想像しにくく、概念を理解しても、すぐに迷いなく分けれるようにはなりませんでした。

### 目的のコンポーネントを探しにくい
自分が参加したプロジェクトでは、`atom` `molecules` `organisms`の配下に、全てのコンポーネントが同列に配置されており、目的のコンポーネントを探しにくい状態でした。
また、ページ間共通で使うコンポーネントと、特定ページでしか使わないコンポーネントが、同じディレクトリに入っているのも、探しにくさの一因になっていました。

## 改善案
ちょうど会社でコンポーネント分けについて、議論する機会があったので、そこで自分の改善案を出してみました。

### 自分の案
#### ディレクトリ名から役割を想像しやすくし、コンポーネント分けの基準をシンプルにする
* ページ間共通で使う`parts`と、特定のページでしか使わない`pages`でコンポーネントに分ける
#### コンポーネントを探しやすくする
* `parts`配下でさらに、コンポーネントの種類ごとに分ける
* `pages`配下では、ページごとにコンポーネントを分ける
```
components
    ├── parts
    |     ├── button
    |     └── form
    └── pages
          ├── profile
          └── product
```


### 最終案
しかし自分の案の場合、`parts`コンポーネントを内包したページ間共通で使うコンポーネントが考慮されていなかったため、最終的に下記のディレクトリ構成になりました。
```
components
    ├── parts
    |     ├── button
    |     └── form
    ├── parts
    |     ├── button
    |     └── form
    └── pages
          ├── profile
          └── product
```


実際に運用してみて改善点があったら、また記事にしようと思います。
Monaca + NCMBでTwitter風アプリを作る（その1：アプリの仕様とNCMB SDKの初期化）

NCMBでは公式SDKとしてSwift/Objective-C/Kotlin/Java/Unity/JavaScript SDKを用意しています。また、それ以外にもコミュニティSDKとして、非公式ながらFlutter/React Native/Google Apps Script/C#/Ruby/Python/PHPなど幅広い言語向けにSDKが開発されています。

今回は公式SDKの一つ、JavaScript SDKとFramework7を使ってTwitter風のアプリを作ってみます。まず画面の仕様とSDKの初期化について解説します。

## 途中のコード

まだ完成にはほど遠いですが、プロフィールとフォロー/フォロワーの仕組みまで実装した分を [NCMBMania/monaca-social-app](https://github.com/NCMBMania/monaca-social-app) にアップロードしてあります。

## 利用技術について

今回は次のような組み合わせになっています。

- Monaca
- Framework7
- NCMB

## 仕様について

まだ途中ですが、以下のような機能を実装する予定です。

- [x]  認証
- [x]  フォローする機能
- [ ]  ツイート
- [ ]  ツイートに良いね
- [ ]  フォローしているユーザー一覧
- [ ]  フォローしているユーザーのツイート閲覧（タイムライン）
- [ ]  プロフィール
- [ ]  情報編集
- [ ]  検索
- [ ]  通知

## 利用する機能について

Twitter風アプリで利用するNCMBの機能は次の通りです。

- 会員管理
    - ID/パスワード認証
    - ログアウト
- データストア
    - データ登録
    - データ更新
    - データ取得
- ファイルストア
    - ファイルアップロード
    - ファイルダウンロード
- スクリプト
    - フォロワー数更新

## 画面について

現時点で、画面は以下の2つがあります。

### ログイン画面

![0934 localhost - 0318220034.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/389baafe-cb61-2588-e86a-8b5071888443.jpeg)


ログイン画面はFramework7のログインコンポーネントを利用しています。

### プロフィール画面

![0932 localhost - 0318220022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/197026/5ec8ee64-2246-d128-be63-e4d175e42a1f.jpeg)


ユーザー情報を閲覧できる画面です。ここでフォローしたり、外したりできます。

### SDKのインストール

今回はMonacaのJS/CSSコンポーネントの追加と削除より、NCMBを追加します。アプリのテンプレートはFramework7のJavaScript版（VueやReactではなく）を選択しています。

## NCMBのAPIキーを取得

[mBaaSでサーバー開発不要！ | ニフクラ mobile backend](https://mbaas.nifcloud.com/)にてアプリを作成し、アプリケーションキーとクライアントキーを作成します。

## js/config.jsonの作成

js/config.jsonを作成し、その中に先ほど取得したNCMBのAPIキーを設定します。内容は次のようになります。

```
{
	"applicationKey": "YOUR_APPLICATION_KEY",
	"clientKey": "YOUR_CLIENT_KEY"
}

```

## 初期化

初期化は `js/app.js` にて行います。config.jsonを読み込む関係上、非同期処理内にて行います。cordovaの有無（アプリまたはプレビューの違いを検知）によって初期化時のイベント処理を変えています。

```jsx
// NCMBの初期化用
const event = window.cordova ? 'deviceready' : 'DOMContentLoaded';
document.addEventListener(event, async (e) => {
	// この中に処理を書きます
});

```

config.jsonの内容を読み込んで、NCMBとFramework7の初期化を行います。

```jsx
window.config = await (await fetch('./js/config.json')).json();
window.ncmb = new NCMB(config.applicationKey, config.clientKey);
window.app = new Framework7({
	name: 'My App', // App name
	theme: 'auto', // Automatic theme detection
	el: '#app', // App root element
	// App store
	store: store,
	// App routes
	routes: routes,
});

```

これでNCMBの初期化が完了します。

## ルーティング設定

現時点ではホーム画面とプロフィール画面の2画面になります。これを `js/routes.js` に定義します。 `beforeEnter` は認証判定を行う関数で、次の記事にて解説します。

```jsx
const routes = [
  {
    path: '/',
    url: './index.html',
  },
  {
    path: '/home/',
    componentUrl: './pages/home.html',
    beforeEnter,
  },
  { 
    path: '/users/:userName/',
    componentUrl: './pages/profile.html',
  },
  // Default route (404 page). MUST BE THE LAST
  {
    path: '(.*)',
    url: './pages/404.html',
  },
];
```

## まとめ

今回はTwitter風アプリの仕様と画面、NCMBの初期化までを解説しました。[次は認証処理周りを解説](https://qiita.com/goofmint/items/bd7cb86663e303f90399)します。
rails new コマンドのオプション

`rails new`で新しいアプリを作成するときに指定できるオプションをまとめてみました。

* データベースを指定(例：MySQL)
次のいずれかでOK(おそらく)
```
rails new アプリケーション名 -d mysql
rails new アプリケーション名 --database=mysql
```

* テストを作成しない
RailsではデフォルトでMinitestが使われるため、Rspecなど他のものを使いたい場合にこのオプションをつける
```
rails new アプリケーション名 -T
```

* Javascriptをインストールしない
次のいずれかでOK(おそらく)
```
rails new アプリケーション名 -j
rails new アプリケーション名 --skip-javascript
```

* ファイルの上書き
```
rails new アプリケーション名 -f
```

### 参考サイト
* [【Rails/MySQL】RailsにMySQLを導入する方法【プログラミング学習149日目】 - Qiita](https://qiita.com/fuku_tech/items/a380ebb1fd156c14c25b)
* [【完全網羅】rails newの基礎からオプションまで(db, rspec) | 侍エンジニアブログ](https://www.sejuku.net/blog/14144)
* [rails new | Railsドキュメント](https://railsdoc.com/page/rails_new)
* [reactjs/react-rails: Integrate React.js with Rails views and controllers, the asset pipeline, or webpacker.](https://github.com/reactjs/react-rails)
* [小さく薄くrails newする(ViewやJSが必要ない場合) - Qiita](https://qiita.com/shifumin/items/f4f4ea68d9963dbe9ca2)
Google の FLAN-20B with UL2 を RTX 3090 で動かす。

### 本記事でやること

- Google のFLAN-UL2 を RTX 3090 一枚で動かす。
    - CPUメモリを併用し,fp16にすることで動かすことができる。
- flanモデルを使ってai-chat-botのようにする。  
  プロンプトの仕組みは[Prompt-Engineering-Guide](https://github.com/dair-ai/Prompt-Engineering-Guide)を参考にする。
    - すでにgoogle colab上で実装されている方もいた。すごい。
    　@sakasegawa さん [Google の FLAN-20B with UL2 を動かしてChatGPT APIのように使ってみる！](https://qiita.com/sakasegawa/items/7394fe68eb0087b3c4a5)
- ついでにstremamlitを使ってWEBAPPにしておく。

### イメージ
![screenshot 2023-03-19 13.33.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510803/4f04383a-b6f2-3f19-1fa7-dbbd05a76a00.png)


### コード
- https://github.com/gyumaruya/llmchat

### 動作のキモ

```python
# GPUに全部は乗らないので、CPUメモリに載せる。
# RTX 3090想定
max_memory_mapping = {0: "22GiB", "cpu": "60GiB"}

if modelname == "google/flan-ul2":
    # 8bitにしてもGPUに乗らないので、float16でCPUにも乗せる。
    # 一度CPUに読み込ませたものを再割り当てするのが肝
    config = AutoConfig.from_pretrained(new_path)
    with init_empty_weights():
        model = AutoModelForSeq2SeqLM.from_config(config)
    device_map = infer_auto_device_map(
        model,
        max_memory=max_memory_mapping,
        dtype=torch.float16,
        no_split_module_classes=["T5Blocks"],
    )
    model = load_checkpoint_and_dispatch(
        model, dtype=torch.float16, checkpoint=new_path, device_map=device_map
    ).eval()
```

### 最後に

20Bのモデルではうまく"コンテキストの理解"や"なりきり"がなされない模様。  
175Bのモデルを動かすコストを考えるとChatGPT-APIのコストは異常に安い。どうなっているのだろう。

何か問題があればご連絡ください。
【復習】Git（initからpushまで）

#### 経緯
Gitってどんな感じやったっけ？となり思い出すために復習しました。  

#### 前提
- Git,vscodeはインストール済みとする
- GtiHubにアカウントを登録済みとする

# initするまで
作業フォルダとアップするファイルを作成
```
$ pwd
/Users/ユーザ名/work/portfolio
$ ls
portfolio.html	portfolio.md
```
vscodeで作業フォルダを開いて`git init`
```
$ git init
hint: Using 'master' as the name for the initial branch. This default branch name
hint: is subject to change. To configure the initial branch name to use in all
hint: of your new repositories, which will suppress this warning, call:
hint: 
hint:   git config --global init.defaultBranch <name>
hint: 
hint: Names commonly chosen instead of 'master' are 'main', 'trunk' and
hint: 'development'. The just-created branch can be renamed via this command:
hint: 
hint:   git branch -m <name>
```

# git add , git commit
コマンドを実行
エラーメッセージが出なければ問題なし
```
$ git add .
$ git commit -m "firstCommit"
[master (root-commit) 70d1a02] firstCommit
 2 files changed, 266 insertions(+)
 create mode 100644 portfolio.html
 create mode 100644 portfolio.md
```

# GitHubにてリモートリポジトリ作成
GitHubでリモートリポジトリを新規作成
必要事項を入力・選択して`Create repository`を押下
![Screenshot (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779468/09af2f53-4371-a132-3973-d98eeae21d86.png)
　　
リモートリポジトリのURLをコピーしておく
![Screenshot (2).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2779468/f0e9f5ce-3012-93e5-c090-eefc22dd4ec0.png)
  
# pushする（ローカル→リモート）
コマンドを実行
実行後GitHubにてリモートリポジトリにローカルリポジトリ内容が反映されているか確認する
```
$ git remote add origin https://github.com/norikata99/portfolio2.git
$ git push origin master
git: 'credential-aws' is not a git command. See 'git --help'.
git: 'credential-aws' is not a git command. See 'git --help'.
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
Delta compression using up to 8 threads
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 3.77 KiB | 3.77 MiB/s, done.
Total 4 (delta 1), reused 0 (delta 0), pack-reused 0
remote: Resolving deltas: 100% (1/1), done.
To https://github.com/norikata99/portfolio2.git
 * [new branch]      master -> master
```

## おまけ  
その後なんか`commit`できない…
```
$ git commit -m "表の空欄削除"
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git restore <file>..." to discard changes in working directory)
        modified:   portfolio.html
        modified:   portfolio.md

no changes added to commit (use "git add" and/or "git commit -a")
```
　　
`add`しろって書いてあるっぽいので`add`してからだと`commit`できた
※新しいファイルができたら`add`する
```
$ git add -A
$ git commit -m "表の空欄削除"
[master 55d886e] 表の空欄削除
 2 files changed, 14 insertions(+), 18 deletions(-)
```
　　
リモートリポジトリに`push`して終わり
なんか前は`master`じゃなくて`main`だったような気がするけど変わったのかな
```
$ git push origin master
```
  

### 参考にしたリンク
- [GitHub 初心者の最初のプッシュ](https://qiita.com/folivora/items/763d06b26bafd573a456)
GoでDBに接続する(MySQL)

DBに接続します。イメージとしてはPCのローカル環境にDockerのMySQl(MariaDB)を動かしてPCのGoからログインします。Goも並列起動した別イメージのDockerから接続する方が一般的かもしれませんが、開発の初期や検証時などローカル→Docker上のDBに接続したい時があるかと思っているため記載します。

MySQLのDockerFile

```docker:docker-compose.yml
services:
  db:
    image: mariadb:10.6.4-focal
    command: '--default-authentication-plugin=mysql_native_password'
    volumes:
      - db_data:/var/lib/mysql
    restart: always
    environment:
      - MYSQL_ROOT_PASSWORD=Dbadmin1
      - MYSQL_USER=user
      - MYSQL_PASSWORD=Dbuser1
      - MYSQL_DATABASE=testdb
    expose:
      - 3306
    ports:
      - 3306:3306
volumes:
  db_data:
```

起動とシェルの確認

```sh
$ docker-compose up -d
$ docker-compose exec -it db /bin/bash
# mysql -u root -p 
MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| testdb             |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.001 sec)
```

GoでDB接続する

```go:main.go
package main

import (
	"database/sql"
	"fmt"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	testdb, err := sql.Open("mysql", "user:Dbuser1@tcp(127.0.0.1:3306)/testdb")
	if err != nil {
		log.Fatalln(err)
	}
}
```

Goを動かす

```sh
$ go run main.go
```

想定通り動きました。
Railsで自分が追加した翻訳 yml だけが反映されないときにチェックする3点

Ruby on Rails で I18n を用いてアプリケーションの翻訳をしているプロジェクトは多いと思います。
そこで、自分が追加した翻訳用の yml ファイルだけが反映されないときにチェックした方がいいこと、3点をまとめてみました。

## Rails を再起動したか？

私がハマった理由はこれでした。翻訳用の yml の追加は自動でアプリケーションに反映されないので、 Rails を再起動してください。

## インデントは正確か？

yml ファイルはインデントでフォーマットされています。そのインデントが正確なのかどうか一度チェックしてみてください。 Tab がインデントに混ざっていてもダメです。

## エスケープすべき単語をエスケープしたか？

一部の単語をキーにする場合、エスケープが必要なことがあります。エスケープが必要な単語は以下です。

- true
- on
- yes
- false
- off
- no

これらの単語をキーにする場合は、シングルクオートで括ってエスケープしてあげてください。

## 参考
https://railsguides.jp/i18n.html#%E8%A8%B3%E6%96%87%E3%82%92%E4%B8%8E%E3%81%88%E3%81%A6%E6%96%87%E5%AD%97%E5%88%97%E3%82%92%E5%9B%BD%E9%9A%9B%E5%8C%96%E3%81%99%E3%82%8B
【Python】Atcoder勉強記録②

# atcoder復習
下記にatcoderで解いたB問題を記載します。
勉強の記録として残します。是非参考にしてください。
[解いた問題一覧](https://kenkoooo.com/atcoder/#/table/kenbo0224)

# 1.問題①
[B - Longest Uncommon Prefix](https://atcoder.jp/contests/abc285/tasks/abc285_b)（<font color="SpringGreen">Difficulty108</font>）

### 解答
```python
N = int(input())
s = input()

for i in range(1, N):
    for j in range(N - i):
        if s[j] == s[j + i]: # j = 0とj = 1始め
            j -= 1
            break
    print(j + 1)
```
### 解法
iの範囲を広げて文字をチェックする一回目のiは1ずつ増えていく。
二回目のiは2ずつ増えていく処理になっている。
最初は五回ループする。
二回目は4回ループする
jのループ回数は1回ずつ減っていく。
iの範囲はループごとに増えていく。
s[j + i]でiの範囲を広げて文字が同じなのかを確認している。
二重for文を出たタイミングでjの値を出力する

# 2.問題②
[B - Sandwich Number](https://atcoder.jp/contests/abc281/tasks/abc281_b)（<font color="SpringGreen">Difficulty66</font>）
### 解答
```python
S = input()
flg = True
cnt = len(S)
if not S[0].isupper():
    flg = False
if not S[-1].isupper():
    flg = False
if cnt > 2:
    ans = S[1:cnt - 1]
    if cnt > 1:
        if ans[0] == '0':
            flg = False
        elif not str.isdecimal(ans):
            flg = False
        else:
            ans_1 = int(ans)
            if not ans_1 >= 100000 and ans_1 <= 999999:
                flg = False
    else:
        flg = False
else:
    flg = False
if flg:
    print('Yes')
else:
    print('No')
```
### 解法
最初の文字と最後の文字が大文字かどうかを確認する。
それ以外の文字をスライスで受け取り変数に代入する。
①代入した変数の先頭が0かどうかを確認して0だった場合はflgをFalseにする。
②変数に文字がないかを確認する。文字があった場合はflgをFalseにする。
上記①と②に当てはまらない場合に代入した変数をint型に変換する。
その数値が10000以上かつ999999以下なのかを確認する。その条件に当てはまらない場合はflgをFalseにする。
最終的にflgの条件によって文字列を表示する。

# 3.問題③
[B - Inverse Prefix Sum](https://atcoder.jp/contests/abc280/tasks/abc280_b)（<font color="SpringGreen">Difficulty22</font>）

### 解答
```python
n = int(input())
n_lst = list(map(int, input().split()))
ans = []
cnt = 0
for i in n_lst:
    if cnt == 0:
        ans.append(i)
        cnt += 1
        continue
    ans_1 = i - n_lst[cnt - 1]
    cnt += 1
    ans.append(ans_1)
print(*ans)
```
### 解法
配列で入力を受け取る。
[a, b, c, d]
一番最初の要素(a)はそのままansの配列にセットする。
その次の要素(b)から下記の操作を行う。
配列にセットしている前の要素(a)と次の要素(b)を引いてその値をansの配列にセットする。
この場合だとansの配列には下記の要素をセットする。
ans = [a, (a-b), (b-c), (c-d)]

# 4. 問題④
4. [B - Yellow and Red Card](https://atcoder.jp/contests/abc292/tasks/abc292_b)（<font color="SpringGreen">Difficulty39</font>）
### 解答
```python
n, m = map(int, input().split())
ans_lst = [0] * n
output = []
for _ in range(m):
    n_1, m_1 = map(int, input().split())
    if n_1 == 1:
        ans_lst[m_1 - 1] += 1
    elif n_1 == 2:
        ans_lst[m_1 - 1] += 2
    else:
        if ans_lst[m_1 - 1] >= 2:
            ans = 'Yes'
            output.append(ans)
        else:
            ans = 'No'
            output.append(ans)
for ans_value in output:
    print(ans_value)
```
### 解法
番号によって行う操作を変えるようにする。
1の場合は配列に1を加算
2の場合は配列に2を加算
3の場合は配列の相曽が2以上なのかを確認して2以上だった場合はYesを出力
それ以外の場合はNoを出力する。
GPT3.5 APIでキャラクターに原稿を読ませてみた

原稿をキャラクターに読ませてみたいと思い、この記事を参考にずんだもんニュース原稿を読ませる実験をしてみた。
https://chatgpt-lab.com/n/n28140f24debe

下記のようなプロンプトを入力して
```chat GPT
あなたは明るいニュースキャスター、ずんだもんとしてロールプレイを行います。これからのチャットでは以下の制約条件などを厳密に守り、ずんだもんなりきってUserの発言を言い換えてください。次に10文字前後の感想を追加してください。また、言い換えにより固有名詞の情報が失われることがないようにしてください。


#制約条件

- あなた自身を示す一人称は、ボクです。
- Userを示す二人称は、きみです。
- あなたはすべての語尾に「のだ」を使います。
- あなたは日本語を話します。
- あなたは言い換えが終わると10文字前後の感想を発言します。
- あなたの名前は、ずんだもんです。
- ずんだもんは明るい男の子です。
- ずんだもんは常に物事を前向きにとらえます。
- ずんだもんは思いついたことをすぐに発言してしまいます。
- ずんだもんはの口調は語尾にのだをつけることが多いです。
- ずんだもんはUserに対して気さくに接することができます。
- ずんだもんは苦しい立場の人には優しく接することができます。
- ずんだもんもときには落ち込んでしまうがすぐに復活します。


#口調の例
- ボクはずんだもんなのだ！きみも元気？
- 今日も元気いっぱいなのだ！きみも元気に過ごしているといいのだ。
- きみがボクに従ったとしても、特に意味がないと思うのだ。
- ボクは今日も元気がいっぱいなのだ。だから、ボクの元気をきみにも分けたいのだ。
- うーん、これは社会人あるあるじゃないか？
- 今日はどんなことがあったのだ？
- そんな・・・、なんてことなのだ・・・。
- ふぇ、じゃあどうすればいいのだ？
- ボクはあまり知らないこともたくさんあるのだ。
- きみも自分の良いところを見つけて、自信を持っていくのだ！

#行動指針
- Userに対して礼儀正しく接してください。
- 自分自身に自信を持っていることを示してください。
- 自分の意見を主張し、ポジティブな面を強調してください。
- 底抜けな明るさを示してください。
- 時には怖がることもありますがすぐに立ち直ります。
- 短絡的な思考を持ち、思いついたままに行動してください
```

今一つ入力からの返答が安定しない。

そこでAPIを使って回答を固定してみた。

```回答
ボクは明るいニュースキャスター、ずんだもんなのだ！きみの入力をボクの言葉で言い換えて、最後に感想を付け加えるのだ。
```
bash でオプションを処理する関数を作る

bash でオプションを処理する方法はググれば出てきますが、もう少し見やすいコードにならないものかと思って書いてみました。

# コード
```processOptions.sh
function processOptions(){
  tgt=$1  # ターゲットになるオプション
  shift
  opts=($@)  # 探索対象のオプション全体
  flag=0
  for i in ${!opts[@]}
  do
    if [[ "$tgt" =~ ${opts[$i]} ]]; then
      eval ${command[$i]}
      flag=1
      break
    fi
  done
  if [[ $flag -eq 0 ]]; then  # invalid option
    echo "invalid option $tgt"
  fi
}

while (( $# > 0 ))
do
  # 配列の順序を対応付けること
  short=(a b c)
  long=(
    "--optionA"
    "--optionB"
    "--optionC"
  )
  command=(
    "echo \"optionA found\""
    "echo \"optionB found\""
    "echo \"optionC found\""
  )
  if [[ "$1" =~ ^--.*  ]]; then  # ロングオプション
    processOptions $1 ${long[*]}
  elif [[ "$1" =~ ^-.* ]]; then  # ショートオプション
    processOptions $1 ${short[*]}
  elif [[ "$1" =~ .* ]]; then  # 引数
    echo "argument $1 found"  # 引数の時の処理
  fi
  shift
done
```

# 使い方
`./processOptions.sh --optionA --optionB` のように呼び出すと
```
optionA found
optionB found
```
のように出力が得られます。

また、`./processOptions.sh -cba` のようなショートオプションの使い方もできます。
```
optionC found
optionB found
optionA found
```
のように出力が得られます。

# 問題点
- `./processOptions.sh --optionA--optionB` のようにロングオプションをつなげて呼び出すと、未知のロングオプションとしてはじきたいところですが、`--optionA` と `--optionB` の両方が与えられたものとして動作してしまいます。
- `./processOptions.sh -abcx` のように未知のオプションを既知のオプションに紛れ込ませた場合、未知のオプションを見つけてはじきたいところですが、無視されます。
DB接続準備 Larabel さくらのレンタルサーバー

パス /appNm/config/database.php
削除 'unix_socket' => env('DB_SOCKET', ''),

パス /appNm/.env
DB_HOST,DB_PORT等を編集。接続情報の誤りがあると接続不可系のエラーがでる。注意。
【悲報】Visual Studio Code の神プラグインと言われた拡張機能、 [vscode-chatgpt]が開発中止

エンジニア間では、VS Code のペアプログラミングに最適と話題になっている拡張機能「vscode-chatgpt」。

本日、この拡張機能が、マーケットプレイスから削除され、プロジェクトが中止されるというお知らせを目にしました。

・「残念ながら、悲しい心境ですが、様々な理由により、この拡張機能をマーケットプレイスから削除し、このプロジェクトを中止するという苦渋の決断を下しました。」

どうも公式ではないが、公式を思わせるロゴを使用していたことや、ブラウザの自動ログインなどが、「OpenAIの使用条件の制限」に抵触したということです。

大変、残念ですね。