OmniAICreator/Qiita-1.07M huggingface dataset:
開発環境周りを整理する

基本的に、Homebrewで管理できるものを使用するようにしています.
webアプリがメインで、フルスタックに開発しています.
フロントエンド、バックエンド、インフラを扱っています.

## 環境
M1 Macbook Air 
M2 pro Mac mini 

## 使用アプリ
### [WezTerm](https://wezfurlong.org/wezterm/)（ターミナルアプリ）
```
brew install --cask wezterm
```  
基本的にコマンドで操作したいため、ほとんどターミナルにいます.
キーバインドなども幅広く設定でき、luaで記述できるのが個人的に良い点です.
難点は、日本語入力が対応していないことです.
入力自体はできるのですが、Ctrl+Hで入力テキストを削除できません.
仕方なく、backspace（delete）で削除しています.


### [neovim](https://neovim.io/)（テキストエディタ）
```
brew install neovim
```  
vimです.（厳密には思想が違うvim）
ずっと使用しているエディタです.
以前は、VSCodeを使用していたのですが、ターミナルに移ったり、マウス操作したりと面倒くさいと感じることが多かったため、vimを使用しています.
自分が操作しやすいようにカスタマイズができるところが良い点です.
自分に最適化されたツールを使うことで生産性爆上がりです.


### [Arc](https://arc.net/)（Chromiumベースブラウザ）
```
brew install --cask arc
``` 
メインブラウザとして使用しています.
ピン留め、ブックマーク、タブをそれぞれ管理できて見やすいのが良いです.
難点は、メモリ爆食いします.
apple silicon RAM 8GBだと、スワップが5GBとか溜まってたりします.
それを考慮しても、使いやすいためずっと使っています.

### [Cyberduck](https://cyberduck.io/)（FTPクライアント）
```
brew install --cask cyberduck
``` 
macを購入してからずっと使用しています.
FTPクライアントって、スタイリッシュなUIなものがないイメージです.


### [Orbstack](https://orbstack.dev/)（docker）
```
brew install --cask orbstack
```   
Docker Desktopの代替です.
パフォーマンスがいいらしいのでこちらを使用しています.
体感、よくわかってません. なんなら比べていません...
macライクなUIなので、それも良い点です.
k8sも扱えます. 


### [Obsidian](https://obsidian.md/)（Zettelkasten）
```
brew install --cask obsidian
```  
メモアプリとして使用しています.
Zettelkasten（ツェッテルカステン）を用いて、システムを構築しています.
そんなに整理やタグ付けはしていないですが...
markdownで書けて、タスクなどを1ファイルにまとるなどができるので便利です.
mermaidも使用できます.

### git
```
brew install git
```  
基本、ターミナルで操作しています.
GUIで操作するよりコマンドで操作したほうが細かいところまで扱えるため便利です.
プログラミングを教える際は、コマンドで操作させるようにしています.
delta を入れて、git diffを見やすくしています


### [fish](https://fishshell.com/)（shell）
```
brew install fish
``` 
ずっと使っているシェルです.
POSIX非互換のため、設定ファイルはzsh等と記述が違います.
[POSIXってなんぞや](https://linuc.org/study/knowledge/402/)
当時は見た目をいじるのが簡単そうだと思い導入しましたが、zshでいいかなと最近思っています.
パッケージ管理は、fisherを使用しています.

### [gh](https://cli.github.com/)（github CLI）
```
brew install gh
```  
コマンドで、issueやprを操作することができます.
pr送るときに、たまに使います


### [ghq](https://github.com/x-motemen/ghq)（リポジトリ管理）
```
brew install ghq
```  
ローカルによしなにクローンしてくれます
管理が楽になります.


### [peco](https://github.com/peco/peco)（インタラクティブフィルタリングツール）
```
brew install peco
```  
fzfと組み合わせて、ローカルリポジトリに早くcdするために入れています.
ghと組み合わせて、リモートリポジトリをクローンすることもできます.


### [fzf](https://github.com/junegunn/fzf)（曖昧検索）
```
brew install fzf
```  
pecoと組み合わせて、リポジトリ検索しています.
あとは、vim上でファイル検索しています.

### [nodenv](https://github.com/nodenv/nodenv)（nodeのバージョン管理）
```
brew install nodenv
```  
nodeのバージョンを管理しています.
基本的にdockerで構築するため、ほぼ使用しません.
vimのプラグイン用です.


### [pyenv](https://github.com/pyenv/pyenv)（pythonのバージョン管理）
```
brew install pyenv
```  
pythonのバージョンを管理しています.
たまに、簡単便利ツールを開発するため、コンテナを立てずにローカルでpythonをゴリゴリ書きます.
ほぼ、vimのプラグイン用です.
Xpdfで帳票PDFファイルをテキストに一括変換する

## やったこと
100件ほどの帳票PDFを内容確認する必要があり、Xpdfを使ってPDF→txtへ変換してgrepで確認できるようにしました

## Xpdfをインストールする
XpdfはPDFビューアとPDF操作ツールが一体となったパッケージソフトです。
今回使ったテキスト変換(pdftotext)以外にも、png変換(pdftopng)やHTML変換(pdftohtml)などがあります。

Mac環境のため主にこちらの記事を参考にしました。

https://qiita.com/tuckKome/items/e69d1ef7170162cae7d6



## ディレクトリ配下のPDFを一括でテキストファイルに変換する

``` bash
cd hoge/
for i (**/*.pdf) pdftotext  -enc UTF-8 -layout -table -f 1 -l 1  "${i}"
```
forコマンドを使ってhoge配下のPDFファイルを全てテキストファイルへ変換します。

- `-enc UTF-8`
    -  xpdfの設定ファイルがうまく読み込めなかったので付与しています。ちゃんと設定すれば不要
- `-layout` `-table` 
    -  PDFのレイアウトを保持して崩れにくくするためのオプション。今回はExcel方眼紙的な帳票だったため付与他にも`-simple`などがあり組み合わせを試して設定しています
-  `-f 1` `-l 1`
    開始ページ(-f)と終了ページ(-l)。帳票の1ページ目だけ取得すれば良かったので付与

変換が成功すると同ディレクトリ内にpdfと同名のテキストファイルが作成されます。

## あとはgrepコマンドでよしなに

今回はデータが単純だったので、grepコマンドで検証に事足りました。
正則化と過学習: L1正則化とL2正則化の役割

## はじめに
機械学習モデルの性能を高めるために、訓練データに対する精度を追求しすぎると、過学習（オーバーフィッティング）が発生する可能性があります。過学習は、モデルが訓練データに対しては高い精度を示すものの、未知のデータに対してはうまく一般化できない状態を指します。この問題を解決するために、正則化（レギュラライゼーション）という技術が用いられます。本記事では、過学習とその対策としてのL1正則化およびL2正則化について詳しく説明します。

## 過学習とは
過学習は、モデルが訓練データのノイズや詳細に過度に適応してしまい、新しいデータに対しての予測性能が低下する現象です。過学習が起こる原因としては、以下のような要因が考えられます。

- 複雑なモデルを使用している
- 訓練データが少ない
- 訓練データにノイズが多い

過学習を防ぐためには、適切なモデルの選択、データの増加、そして正則化が重要です。

## 正則化とは
正則化は、モデルの複雑さを抑え、過学習を防ぐための技術です。正則化にはいくつかの種類がありますが、代表的なものとしてL1正則化（Lasso）とL2正則化（Ridge）が挙げられます。

## L1正則化（Lasso）
L1正則化は、モデルの重みの絶対値の和にペナルティを課す手法です。L1正則化の目的は、重みの一部をゼロにすることによって特徴選択を行い、モデルをスパースにすることです。これにより、モデルの複雑さが減少し、過学習を防ぎます。L1正則化の数式は以下のようになります。

```math
\text{Loss} = \text{Loss}_{\text{original}} + \lambda \sum_{i} |w_i|
```

ここで、\(\lambda\)は正則化の強さを制御するハイパーパラメータです。

#### L1正則化の利点
- 特徴選択が自動的に行われる
- スパースモデルが得られる

## L2正則化（Ridge）
L2正則化は、モデルの重みの二乗和にペナルティを課す手法です。L2正則化は、重みが大きくなりすぎないようにすることで、モデルの複雑さを抑えます。L2正則化の数式は以下のようになります。

```math
\text{Loss} = \text{Loss}_{\text{original}} + \lambda \sum_{i} w_i^2
```

#### L2正則化の利点
- 過学習の防止
- すべての特徴が均等に扱われる

## L1正則化とL2正則化の違い
L1正則化とL2正則化はどちらも過学習を防ぐための有効な手段ですが、その動作原理や結果には違いがあります「L1正則化」は**特徴選択**を行うため、モデルをシンプルに保ちます。一方、「L2正則化」は**すべての特徴を均等に扱う**ため、特定の重みが大きくなるのを防ぎます。いずれにせよ過学習を抑制するためには**正則化パラメータを増やす**必要があると言えます。

### 実装例
L1正則化およびL2正則化は、多くの機械学習ライブラリでサポートされています。以下に、PythonのScikit-learnライブラリを使用した回帰モデルにおける実装例を示します。
```
from sklearn.linear_model import Lasso, Ridge
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_regression

# データの準備
X, y = make_regression(n_samples=100, n_features=20, noise=0.1, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# L1正則化 (Lasso) 回帰
lasso = Lasso(alpha=0.1)
lasso.fit(X_train, y_train)
lasso_pred = lasso.predict(X_test)

# L2正則化 (Ridge) 回帰
ridge = Ridge(alpha=0.1)
ridge.fit(X_train, y_train)
ridge_pred = ridge.predict(X_test)
```

## 結論
正則化は、過学習を防ぎ、モデルの一般化性能を向上させるための重要な手法です。L1正則化とL2正則化は、それぞれ異なる方法でモデルの複雑さを抑えます。L1正則化は特徴選択を行うのに対し、L2正則化は重みの大きさを抑えます。適切な正則化手法を選択することで、より良いモデルを構築することができます。

今後のモデル開発において、正則化の理解と適用は重要なスキルとなります。是非、この技術を活用して、より効果的な機械学習モデルを構築してください。
rails パンくず  gretelを使った

# GemFileを追加
````
#breadcrumbs
gem "gretel"
gem 'gretel-jsonld'
````
# gem インストール
````
 rails g gretel:install
````

# パンくずリスト作成

1. config\breadcrumbs.rbが作成される
→ コメントなどを参考に記述

# パンくずタグ書き方
	<% breadcrumb :works %>
	<%= breadcrumbs style: :ul, class: 'pankuzu-list' %>

上記簡単説明
works → config\breadcrumbs.rb内の定義とひもづく
style: :ul → ul, liタグでつくるという命令
class: 'pankuzu-list' → ulタグにpankuzu-listというcssをつけるという命令

# パンくず構造化タグの追加
<%= jsonld_breadcrumbs %>
YOLOv9を使って３分でやる物体検出

# はじめに
今回はYOLOv9を用いた物体検出をやっていきます． YOLOは手軽に使えるとても強力なモデルです． 複雑な環境構築なしですぐに物体検出を行えるので，ぜひ試してみてください！

https://github.com/WongKinYiu/yolov9

# 実行環境
OS：macOS Sonoma
Python：3.12.3

# YOLOv9とは
YOLOは「You Only Look Once」の略で，その名の通り画像を一度だけ見て処理を行う機械学習ベースのアルゴリズムです．YOLOの特徴は，**一定水準の精度を保ちながら高速かつ軽量に動作すること**です．  
YOLOv9は2024年2月に公開されたモデルで，効率性，精度，適応性でこれまでのモデルよりも高い水準を誇っています．

<img width="500px" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3298420/39a0c5c3-6cb0-aa24-ce4d-e755c5d265b7.png">

深層学習の「深い層に行くほど元の情報が失われる」といった課題に対処するため，**Programmable Gradient Information(PGI)** というコンセプトと，**Generalized ELAN(GELAN)** というアーキテクチャを提案しました．これによって，モデルの性能を向上させると同時に，計算コストを削減し，リソースが限られている環境でも高い性能を発揮することが可能となりました．
詳しい内容は元の論文を参照ください．

https://arxiv.org/abs/2402.13616

# 環境構築
それでは，早速YOLOv9を試していきたいと思います．まずは簡単な環境の構築からです．
## 仮想環境を作成
```
python3 -m venv yolovenv
cd yolov9env
source bin/activate
```

## YOLOv9を用意する
```
git clone https://github.com/WongKinYiu/yolov9.git
cd yolov9
pip3 install -r requirements.txt
wget -P weights -q https://github.com/WongKinYiu/yolov9/releases/download/v0.1/yolov9-c.pt
```
これだけでObject Detectionができるのは嬉しいですね！

# 実行してみる
それでは，YOLOv9を用いてObject Detectionをやってみましょう！
`yolov9`フォルダの中で以下のコマンドをたたきます．

```
python detect.py --weights weights/yolov9-c.pt --conf 0.1 --source data/images/horses.jpg --device cpu --exist-ok
```
cudaの環境がないので，`--device cpu`とします．すると，以下のようなエラーができてきました．
```
AttributeError: 'list' object has no attribute 'device'
```
このエラーについては[こちらのissue](https://github.com/WongKinYiu/yolov9/issues/11)で解決されており，`utils/general.py`の**903行目**を以下のように修正します．
```python: general.py
prediction = prediction[0][0]  # select only inference output
```
再度実行してみると，`runs/detect/exp`フォルダが生成され，その中に結果画像が出力されます．

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3298420/eaf0f05f-046d-ab4a-8d95-dc1a188cbf64.jpeg">

物体検出ができましたね！学習やパラメータ調整も容易にできるので試してみてください！

# まとめ
今回はYOLOv9を用いて簡単な物体検出を行いました．前バージョンのv8よりも格段に性能が上がっており，リアルタイムな検出やトラッキングにも活用できると思います．
環境構築で詰まらずに実践できる機械学習はとても魅力的ですね✨
OVRPlayerController を使うと落っこちる

UnityもC#もわからずMetaQuestをいじっている人の自分用雑メモです．

***
OVRCameraRigだと機能が足りないのでOVRPlayerControllerに変更したところ，眼の前にあるはずのオブジェクトが表示されない．ログを見る限りちゃんとインスタンス化されてるし，なんなら起動時一瞬だけオブジェクトが見えるのはなんなんだ・・・と困っていたらどうやらカメラが落っこちているっぽい．

それっぽいところはここ．

```OVRPlayerController.cs
protected virtual void UpdateController()
{
    ///略
    
    if (Controller.isGrounded && FallSpeed <= 0)
            FallSpeed = ((Physics.gravity.y * (GravityModifier * 0.002f)));
    else
            FallSpeed += ((Physics.gravity.y * (GravityModifier * 0.002f)) * SimulationRate * Time.deltaTime);

    moveDirection.y += FallSpeed * SimulationRate * Time.deltaTime;

    ///略
}
```

# 解決法
というわけで落ちないようにするには床を追加するか，インスペクタでGravityModifierを0にすれば落ちなくなるよ．
![スクリーンショット 2024-06-12 10.57.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3809718/e7c0d060-7ab3-5cc4-de4a-13e937fc653d.png)
GoogleスプレッドシートのImage関数でGoogleDrive上の画像を持ってくる方法

先日スプレッドシートに画像を埋め込む際に少し苦戦したので備忘録として書き留めておきます。

:::note warn
初心者なので少し日本語が拙い部分や正確とは限らない部分がある可能性がありますがご了承ください。
:::

## 1.Image関数とは
Googleが提示してる関数はこれです。 
```
IMAGE(URL, [モード], [高さ], [幅])
```
このURLに対象の画像のURLを貼るとセルに表示されます。

例えばこんな感じ。

```
IMAGE("https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png")
```

これをいれると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/d960713c-a7a2-7f26-f0f4-05ea2cf8f09e.png)

こんな感じで該当の画像が表示できます。

## 2.本題
ではこれをGoogleDriveにおいた画像でやるとどうなるか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/2afa5071-e000-3ea6-d105-0ba491f5952e.png)
GoogleDriveにある画像を開いたリンクを先程の関数にいれると

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/c22aa888-4377-7a29-9309-5a873a0d81fa.png)

**こうなります**

真っ白ですね。こうなってしまい画像を貼り付けることはできません。
しかもGoogleの説明にはこう書かれています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/83861f71-d887-adb6-bba1-c655bac397c2.png)

どうやらだめなようです。

## 3.方法
ではどうやっていれればいいのでしょうか。

#### 1.該当の写真を開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/d58678c7-207d-e2b1-aa57-8bbe71146ba0.png)

このように埋め込みたい画像をGoogleDrive内でひらきます。

#### 2.開発者ツールを開く
ChromeならF12キーで開けます。
開くとこんな物が出ます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/ae370090-ce36-d23c-4292-0daccd558abd.png)
左上にある四角に矢印が刺さってるものを押します。
押したものが青くなっている状態で、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/985da6c3-b9e9-edd0-56af-4088a34ccc30.png)
このように画像部分を選択すると、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/c354d655-a2b7-d874-ff68-0e07af8b969a.png)
こんな物が出てきます。
この＜img src="URL"＞のURLの部分が画像のURLになります。
試しにこのURLをコピーして貼り付けてみると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3799004/d1ae96fa-540e-0fae-4fac-3dc9f064072d.png)

表示できました！
（画像は https://kotonohaworks.com/free-icons/user/ をお借りしております。）

## 4.あとがき
今回は開発者ツールを使ってリンクを取得しましたが、実はかなりめんどくさい方法のようで、調べたら他にURLをいじる簡単なやり方もありました。
このやり方の注意点としましては

**実は共有していなくても画像にアクセスできてしまう**

ので少しセキュリティ的に危ない可能性がありますので十分注意して使うようにしましょう。
Cognos Analytics 12.0.3 コンテンツ削除ルール発動動作の最適化

# 概要
Cognos Analytics 12.0.3でコンテンツ削除ルール発動時の動作が最適化されていますので共有です。
削除ルールとは、レポートを保存済みとして保存した時の、古いバージョンの保存済みレポートの削除です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/147246/deb8e81a-46ad-456b-d41a-5b439b63b3e6.png)

# 参考情報
Faster processing of content retention rules
https://www.ibm.com/docs/en/cognos-analytics/12.0.0?topic=components-faster-processing-content-retention-rules

# 詳細説明
これまでのCognos Analyticsのバージョンでは、レポートを保存済みレポートとして作成するタイミングで、古いバージョンの削除処理を行っていました。
この動作のため、例えばバーストレポート等で大量の保存済みレポートを同時に作成し、古いバージョンが同時に削除される処理では、一連の処理が長時間かかってしまう問題がありました。
この問題を解消するため、Cognos Analytics 12.0.3以降のバージョンでは、古いバージョンの削除処理は非同期で行われるようです。

この動作の変更により、以下のメリットがあります。
- 保存済みレポートの作成または更新処理が高速に実行されます。
- 削除操作は小さなバッチで実行されるため、トランザクション・サイズが削減されます。
- 期限切れのオブジェクト (期間ベースの保存ルールによって制御される) は、時間どおり (約 10 分以内) に削除されるようになりました。

以下の2つのパラメーターにより削除動作を調整できます。
**CM.RETENTIONS_EXPIRATION_CHECK_INTERVAL**
ルールに当てはまる古いバージョンが存在するかをチェックする間隔です。当てはまる場合、該当のバージョンは削除フラグが付与されます。
デフォルトは60秒です。

**CM.RETENTIONS_OUT_OF_SCOPE_CHECK_INTERVAL**
削除フラグが立っているバージョンをチェックする間隔です。当てはまる場合、該当のバージョンはContent Storeから削除されます。
デフォルトは60秒です。

# 注意点
この削除最適化の機能の実装のため、Content Storeのテーブル構造に更新が入っているようで、Cognos Analytics 11.2.4 FP3と12.0.3に入っているようです。
つまり、12.0.1と12.0.2には入ってないので、Cognos Analytics 11.2.4 FP3の環境をバージョン12にアップグレードする場合、必ず12.0.3以降を選択する必要があります。
とのこと、まあ自然に最新バージョン選択すれば問題ないとは思いますが、なぜか古いCognos Analytics 12のバージョンを選択するという時は気を付けましょう。
dockerで不要イメージ削除 容量圧迫

・ 不要なイメージ確認
````
docker images
````

<none>といういらなそうなものが増えている。
```
sudo docker images
REPOSITORY              TAG       IMAGE ID       CREATED         SIZE
docker-app_green        latest    fc8040859914   23 hours ago    1.29GB
docker-app_blue         latest    dcff5ba9f2c1   23 hours ago    1.29GB
<none>                  <none>    a0acad96687d   23 hours ago    1.29GB
docker-nginx            latest    5917ff47250b   23 hours ago    188MB
<none>                  <none>    575c4b963b31   23 hours ago    188MB
<none>                  <none>    cf8c1244c8f7   24 hours ago    188MB
<none>                  <none>    f8729a190322   24 hours ago    188MB
<none>                  <none>    f0dcd3552e40   24 hours ago    188MB
<none>                  <none>    c03d023930bd   24 hours ago    188MB
<none>                  <none>    73305d0f299c   24 hours ago    188MB
<none>                  <none>    ed2eb388f593   24 hours ago    188MB
<none>                  <none>    b297f82ec0fc   41 hours ago    188MB
<none>                  <none>    4290516ccf44   43 hours ago    1.29GB
<none>                  <none>    94b5fd7c78fc   6 days ago      1.25GB
docker-blue             latest    f4e615fe688e   10 days ago     1.23GB
mariadb                 11.3      3ba807438681   2 weeks ago     405MB
phpmyadmin/phpmyadmin   latest    933569f3a9f6   10 months ago   562MB
```

不要イメージ削除コマンド
````
sudo docker image prune
````
結果
````
WARNING! This will remove all dangling images.
Are you sure you want to continue? [y/N] y
Deleted Images:
deleted: sha256:c03d023930bd0eec8b4e2ca3cebd30618c1c7116bf176a7b8f52e51ac3ff597e
deleted: sha256:94b5fd7c78fc067df490ea4675cdb5eb7256f8c4d8bc9840c4d50f028346757b
deleted: sha256:f0dcd3552e404447cb48e21ede718417df32892f125cf71c2df8cd186fc9647c
deleted: sha256:b297f82ec0fc357bc0e4d8c472acc9b392617f850af1e7c9949018cf00f99fe5
deleted: sha256:f8729a190322be835ab832bcc75436352eaec3da43464207b4c352cbe9734d7c
deleted: sha256:cf8c1244c8f7660a364e6f711cbb0dc0d9ef21677592b582eb682edb0a611464
deleted: sha256:ed2eb388f59355fd2d9163564652bb54743f7217a3615942b4fb7e88852ca646
deleted: sha256:575c4b963b31cee580908d3d068ab90ebbeb61b19e9678f71058dab3fb7c3ab4
deleted: sha256:a0acad96687d561adab546dbffac9a59c6a4d9dbed608f54d1234a75b04e8e66
deleted: sha256:73305d0f299c74130042dd63ee4ac2d6b85a6f2cbaa9f51725baa2b4b70952bc
deleted: sha256:4290516ccf4473de0b892bb2bda3ef49bfd9bc6b258d4eeae29f6dae6069d24b
````
Beginner picoMini 2022 writeup PW Crack 5

## PW Crack 5 (General Skills)

Can you crack the password to get the flag? Download the password checker here and you'll need the encrypted flag and the hash in the same directory too. Here's a dictionary with all possible passwords based on the password conventions we've seen so far.

添付ファイル
・level5.py
・level5.flag.txt.enc
・level5.hash.bin
・dictionary.txt

dictionary.txtを見てみると、パスワード候補が各行4桁ずつ書かれていた。PW Crack 4とほぼ同じであるが、dictionary.txtを読み込んでパスワード候補を改行区切りでリストに格納する必要がある。
以下、実行コード。

```python
import hashlib

### THIS FUNCTION WILL NOT HELP YOU FIND THE FLAG --LT ########################
def str_xor(secret, key):
    #extend key to secret length
    new_key = key
    i = 0
    while len(new_key) < len(secret):
        new_key = new_key + key[i]
        i = (i + 1) % len(key)        
    return "".join([chr(ord(secret_c) ^ ord(new_key_c)) for (secret_c,new_key_c) in zip(secret,new_key)])
###############################################################################

flag_enc = open('level5.flag.txt.enc', 'rb').read()
correct_pw_hash = open('level5.hash.bin', 'rb').read()
pw_candidate = open('dictionary.txt', 'r').read()


def hash_pw(pw_str):
    pw_bytes = bytearray()
    pw_bytes.extend(pw_str.encode())
    m = hashlib.md5()
    m.update(pw_bytes)
    return m.digest()


def level_5_pw_check(user_pw):
#    user_pw = input("Please enter correct password for flag: ")
#    user_pw_hash = hash_pw(user_pw)
    
#    if( user_pw_hash == correct_pw_hash ):
        print("Welcome back... your flag, user:")
        decryption = str_xor(flag_enc.decode(), user_pw)
        print(decryption)
        return
        print("That password is incorrect")

pw_list = pw_candidate.split()
for i in pw_list:
    if hash_pw(i) == correct_pw_hash:
        a = i


level_5_pw_check(a)
```

`picoCTF{h45h_sl1ng1ng_40f26f81}`
Minecraftサーバーを2つ以上の常時起動ではないPCで協力して起動してあげる方法

# 注意
最初にいいますがおすすめしません。
適当にやってたらできた、ということを共有したかっただけですしすごい技術を使ったわけでもありません。
諸事情でどうしても常時起動ができないけど常時起動したい、という場合にしか適用できるものではありませんので、プロダクションやらなんやらで使うことを念頭に書いていません。それだけはご承知おきください…

# tl;dr

クラウドストレージを使うだけです。
友人のPCと共有したいのならばOneDriveかGoogle Driveにフォルダを作って共有し、それをストレージに落としておきます。
そのフォルダの中にサーバーを構築すれば準備は終わりです。

起動するたびに大量にファイルが同期されます…。
そして同期が中途半端なときに起動してしまうと競合が発生してまたさらに大量にファイルが発生してしまいますので連絡を取り合って起動するのがおすすめです。

なお個人的観測として、ワールドを進めると毎回結構な時間（10分ぐらい）が同期に必要ですので時間に余裕をもって行いましょう。

# 終わり
本当に誰に需要があるのかよくわかりません。
ネット上にこれに関するリソースがなかったので書いただけでして、もしクラウドストレージでもできるのかな？と迷っている方の助けになれば幸いです。
tscでHoge.tsとhoge.jsが混在する


# 環境

| name             | version |
| ---------------- | ------- |
| Windows11        | 23H2    |
| tsc              | 5.4.5   |
| node             | 20.9.0  |
| npm/npx          | 10.5.1  |
| electron         | 27.0.3  |
| electron-builder | 24.13.3 |

# 問題

electron コマンドで実行した際には正常に動くのに、electron-builder でビルドして実行すると cannot find module となり困っていた。
tsc 並びに electron コマンドが通るので、もちろんファイル名は正しい（つもりだった）。

![こんなエラーが出る](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3797993/df558be8-64df-e795-d9d4-803da3283a11.png)

::: note warn
Error:Cannot find module
require 文で Cpu.class.js モジュールが見つからない。
:::

# 原因と解決

以下、コンパイルは tsc によるもの。
hoge.ts をコンパイル後、Hoge.ts （先頭大文字）にリネームしたことが原因だった。
リネーム後再度コンパイルしても、hoge.js が更新されるだけで Hoge.js は生成されない。
一度 hoge.js を削除してからコンパイルすれば Hoge.js が生成される。

> root/
> ├ Hoge.ts
> └ hoge.js
> こういう構成のとき困るという話

また、tsc は.ts ファイルを見てモジュールが存在するかどうか判断する。
そのため Hoge.ts と hoge.js がある状態だと、"Hoge"を import しないと警告が出る。（tsconfig の [forceConsistentCasingInFileNames](https://zenn.dev/chida/articles/bdbcd59c90e2e1#forceconsistentcasinginfilenames) が true の場合）
しかし、コンパイル後には"hoge"モジュールである。ややこしや～
laravelでS3からファイル取得

# 前提
・ コンポーザーで以下が入っている。
```
composer require aws/aws-sdk-php
```
・ copnfig/app.phpなどAWS用のライブラリ設定済み(こういうの)
```
  'providers' => array(
        // ...
        Aws\Laravel\AwsServiceProvider::class,
    )

'aliases' => array(
        // ...
        'AWS' => Aws\Laravel\AwsFacade::class,
    )
```
・ config/aws.php設定済み （こういうの）

```
<?php

use Aws\Laravel\AwsServiceProvider;

return [

    /*
    */
    'credentials' => [
        'key'    => env('AWS_ACCESS_KEY_ID', ''),
        'secret' => env('AWS_SECRET_ACCESS_KEY', ''),
    ],
    'region' => env('AWS_REGION', 'us-east-1'),
    'version' => 'latest',
    'ua_append' => [
        'L5MOD/' . AwsServiceProvider::VERSION,
    ],
];
```
# AWSコンソールからアクセスキーとシークレットアクセスキーを取得

・サービスからIAMへ
・メニューからユーザを選択
・ セキュリティー認証情報からアクセスキーを作成
→ csvがダウンロードできる
・laravelへ設定
.envにそれぞれ設定
```
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
```

以下のようなコードでS3からデータ取得できる
```
<?php

namespace App\Console\Commands;

use Aws\S3\S3Client;
use Config;
use Illuminate\Console\Command;

class LoanInitialRate extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'import:loan_initial_rate';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        $s3 = new S3Client([
            'credentials' => Config::get('aws.credentials'),             // aws上では省いたほうが良さそうなのでちょっとそこはわけたほうがよいかも(推測)
            'version' => 'latest',
            'region' => 'ap-northeast-1'
        ]);
        $s3_list = $s3->ListObjects([
            'Bucket' => 'c21-ftp-server-stg',//バケット名
            'Prefix' => "mng",//ファイル指定
        ]);

        foreach ($s3_list['Contents'] as $object) {
            echo "ファイル名: " . $object['Key'] . "\n";
        
            // 各ファイルの内容を取得
            $file = $s3->getObject([
                'Bucket' => 'c21-ftp-server-stg',
                'Key'    => $object['Key']
            ]);
        
            // ファイル内容を表示
            $content = $file['Body']->getContents();
            echo $content . "\n";
        }        
        

    }

}
```
端末が i386 かどうかワンライナーで確認する方法

環境変数 hw.machine_arch の戻り値で i386 なのかどうか確認するワンライナー
arm とか amd64 とかはその他処理もするんw

```sh:ワンライナー i386 なら ok それ以外 ng を返す
( sysctl -n hw.machine_arch | grep -q i386 ) && echo ok || echo ng
```
Python Ruff

PythonのFormatterとLinterとしてRuffを使用する。

```bash.sh
pip install ruff ipykernel
```

```.pyproject.toml
[tool.ruff]
extend-include = ["*.ipynb"]
line-length = 88

```

```.vscode/extensions.json
{
    "recommendations": [
        "charliermarsh.ruff",
        "ms-python.python"
    ],
}
```

```.vscode/settings.json
{
    "notebook.formatOnSave.enabled": true,
    "notebook.codeActionsOnSave": {
        "notebook.source.fixAll": "explicit",
        "notebook.source.organizeImports": "explicit"
    },
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",
        "editor.formatOnSave": true,
        "editor.codeActionsOnSave": {
            "source.fixAll": "explicit",
            "source.organizeImports": "explicit"
        },
    }
}
```
PostgreSQL UNION、UNION ALLのデータ型不一致エラー

業務中に出会ったエラー。

### テーブル
student、parentテーブル
|No |物理名  |データ型 |
|--- |---|---|
|1 |name|text|

teacherテーブル
|No |物理名  |データ型 |
|---|---|---|
|1|name|text|
|2|age|numeric|


### エラーが発生するSQL

```sql
select name, null as age from student
union all
select name, null as age from parent
union all
select name, age from teacher
```

### エラー内容
`UNION types text and numeric cannot be matched`
型が一致していないよ、というエラー。
UNION、もしくは、UNION ALLを使用する場合、結合されるすべてのSELECT文の対応する列のデータ型が一致している必要がある。
が、nullの型が指定されていない場合、textと判断される模様。

### 対処法
```sql
select name, null::numeric as age from student
union all
select name, null as age from parent
union all
select name, age from teacher
```
`null::numeric as age`と明示的に型を指定することで、型不一致のエラーが回避できる。

### ちなみに

* 型が明示的なselect文を2番目までに記載している場合

```sql
select name, age from teacher
union all
select name, null as age from student
union all
select name, null as age from parent
```
または
```sql
select name, null as age from student
union all
select name, age from teacher
union all
select name, null as age from parent
```

この場合はエラーが発生しない。
【Ruby】世界恐慌が本当に木曜日から始まったのかを検証してみた

## はじめに
＊この記事は、Rubyを使えば簡単に曜日を算出できるということを伝えたいという思いから生まれたものです。

さて、皆さんは「世界恐慌」と呼ばれるものを知っていますでしょうか？

おそらくご存知でしょうが、念のため簡単に説明しておきます。
### 世界恐慌とは？
１９２９年１０月２４日にニューヨーク・ウォール街の株式取引所で株価が大暴落したことによって世界的な不景気に突入しました。
これを世界恐慌といいます。
また、この株価大暴落は「暗黒の木曜日」とも言われいます。
### 暗黒の木曜日（1929年10月24日)って本当に木曜日？
世界恐慌の始まりが「暗黒の木曜日」と呼ばれていることについて、今更不信感を覚えたのでRubyを用いて検証しようと思います。

## Rubyで曜日を計算する方法は？
`.wday`メソッドを使うと、曜日を０（日曜）から６（土曜）の数字で表現することができます。
具体的な使用方法は以下のコードをご覧ください。
```check.rb
# 今日は2024年6月3日(月)です。
week = ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日']
now = Date.today
pp now.wday # 1
pp week[now.wday] # '月曜日'
```

## いざ検証
では実際に、世界恐慌(1929年10月24日）が木曜日なのかを検証しようと思います。
```check.rb
week = ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日']
great_depression_date = Date.new(1929, 10, 24) # great_depression: 世界恐慌
pp week[great_depression_date.wday] # '木曜日'
```
わかってはいましたが、やはり木曜日でしたね。

## 結論
- `.wday`を使うと曜日を０（日曜）から６（土曜）の数字で表現することができる。
- 世界恐慌は本当に木曜日だった
S3ACL詳細

```auto.sh
LIST_FILE="s3li.txt"

while IFS= read -r line; do
  echo "$line"
  aws s3api get-public-access-block --bucket ${line} --output text
done < "$LIST_FILE"
```

```コマンド
aws cloudwatch list-metrics --namespace AWS/EC2 --metric-name NetworkIn --query "Metrics[].Dimensions[*].[Name, Value]" --output text
```
Kubernetesクラスタ上で、CNIがネットワークの不具合解決メモ

# 概要
Kubernetes内のflannelがネットワークインターフェースを作成できなくなったので、解決手段のメモを残す

# 原因を調べる

対象のノードにsshでログインして、`ip a`コマンドを実行して、`flannel.1`がないのでflannelが悪さしているとあたりをつけた。

# 失敗した方法について

## flannelのPodを削除して再起動
以下のコマンドで対象のノードで動いているflannelのpodを調べて`delete`コマンドでそのpodを削除する。
```bash
kubectl -n kube-flannel get pod -o wide
```

上記を実行してもネットワークインターフェースが作成されない


# 成功した方法

以下のコマンドで、k8sクラスタから切り離す
```bash
sudo kubeadm reset
```
切り離し後、cniフォルダを削除
```bash
sudo rm -fr /var/lib/cni
sudo rm -fr /etc/cni/net.d
```
上記のあと、control-planeから登録を削除する

以下のコマンドで、`kubeadm`で`join`するためのコマンドを作成する
```bash
echo sudo kubeadm join $(hostname -I|awk '{print $1}'):6443 --token $(kubeadm token list |sed -n 2P|awk '{print $1}') --discovery-token-ca-cert-hash sha256:$(openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //')
```

作成した、コマンドでk8sクラスタに再接続することで`flannel.1`のネットワークインターフェースが作成したので、対象のnodeを再起動すると、cni0も作成されることを確認したので一応復旧ができた。
【csh】SQL*Plus・Loaderのインストール

# Oracle Instant Clientのインストール

1. Oracle Instant Clientのダウンロード

Oracleの公式サイトからOracle Instant Clientをダウンロードします。以下はダウンロードページのURLです：

・[Oracle Instant Client ダウンロード](https://www.oracle.com/database/technologies/instant-client/downloads.html)

2. 必要なパッケージのダウンロード

必要なパッケージは以下の通りです：
| パッケージ |
|:-:|
| Instant Client Basic   |
| Instant Client SQL*Plus  |
| Instant Client SQL*Loader   |

```
adm/adm[59]: ls -l /home/yuya/ダウンロード
合計 226072
-rw-rw-r-- 1 yuya yuya  68965195  6月  7 16:43 instantclient-basic-linux.x64-12.2.0.1.0.zip
-rw-rw-r-- 1 yuya yuya    904309  6月  7 16:45 instantclient-sqlplus-linux.x64-12.2.0.1.0.zip
-rw-rw-r-- 1 yuya yuya   1132671  6月  7 16:44 instantclient-tools-linux.x64-12.2.0.1.0.zip
```

3. ダウンロードしたパッケージのインストール

以下のコマンドを使ってパッケージを解凍し、適切なディレクトリに配置します。今回は/opt/oracleに配置します。

```
# 必要なディレクトリを作成
sudo mkdir -p /opt/oracle
cd /opt/oracle

# ダウンロードしたパッケージをコピー
sudo cp ~/ダウンロード/instantclient-sqlplus-linux.x64-12.2.0.1.0.zip .
sudo cp ~/ダウンロード/instantclient-tools-linux.x64-12.2.0.1.0.zip .
sudo cp ~/ダウンロード/instantclient-basic-linux.x64-12.2.0.1.0.zip .

# パッケージを解凍
sudo unzip instantclient-sqlplus-linux.x64-12.2.0.1.0.zip
sudo unzip instantclient-tools-linux.x64-12.2.0.1.0.zip
sudo unzip instantclient-basic-linux.x64-12.2.0.1.0.zip

# シンボリックリンクを作成
cd instantclient_12_2
sudo ln -s libclntsh.so.12.1 libclntsh.so
```

４．環境変数の設定
~/.cshrcまたはシステム全体の設定ファイルに環境変数を追加します

```
# Oracle Instant Clientの環境変数を設定
setenv ORACLE_HOME /opt/oracle/instantclient_12_2
setenv LD_LIBRARY_PATH $ORACLE_HOME:$LD_LIBRARY_PATH
setenv PATH $ORACLE_HOME:$PATH

```

これらの設定を行った後、source ~/.cshrcコマンドを実行して環境変数を更新します。
```
source ~/.cshrc
```
【Ubuntu】画面をフルスクリーンに変更する方法

VirtualBoxでUbuntuを起動し、画面を最大化しても元の画面のままになってしまう。

これを解決するには以下の手順を実施した。

## 1.Guest Additionsのインストール：

Guest Additionsをインストールすることで、仮想マシンの画面解像度の自動調整が可能になります。
手順を再掲します：

（１）仮想マシンを起動し、ログインします。
（２）VirtualBoxのメニューから「デバイス」→「Guest Additions CD イメージの挿入」を選択します。
（３）ゲストOS内でCDイメージがマウントされ、自動的にインストーラが起動します。もし自動的に起動しない場合は、手動でマウントされたCDドライブに移動し、インストーラを実行します。
（４）インストールが完了したら、仮想マシンを再起動します。

## 2.画面の自動リサイズ機能の有効化：

仮想マシンのウィンドウメニューから「表示」→「自動リサイズゲストディスプレイ」を選択します。これにより、ホストマシンのウィンドウサイズに応じて仮想マシンの解像度が自動的に調整されます。

## 3.解像度の手動設定：

ゲストOS内で解像度を手動で設定することもできます。
Windowsの場合：
デスクトップを右クリックし、「ディスプレイ設定」を選択します。
解像度のドロップダウンメニューから適切な解像度を選択します。
Linuxの場合：
「設定」→「ディスプレイ」を開き、解像度を設定します。

## それでも解決しない場合
解像度が下がるが、表示倍率を100％から150％に調節すると、画面が大きくなり見やすくなる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3782903/51bc88b5-e247-4581-9bab-df3311d31c30.png)
「現場で使えるRuby on Rails 5 速習実践ガイド」の内容を最新バージョンでやってみた


# はじめに
「現場で使えるRuby on Rails 5 速習実践ガイド」にてrailsを勉強中なのですが、本書はバージョンが古く、最新バージョン(2024/06現在)ではruby/rails/etc..などで差異があるので書き残していく。
本書と同様の環境を作ろうと奮闘しましたが、相次ぐサポート切れとエラーを乗り越えrailsのインストールまで漕ぎつけたものの肝心のプロジェクト作成で転けて解決できず、渋々最新バージョンへ乗り換えました。([爪痕](https://qiita.com/yuuya-apple/items/7db6010bb13a3f545569))

# 使用バージョン
ruby:3.2.1
rails:7.1.3.4
gem:3.4.6
bootstrap:5.3

# erbからslimへのコンバート
本書では`html2slim`を仕様してerbからslimへのコンバートを行っていますが、記載通りの手順で行うとエラーになります。
``` shell
$ bundle exec erb2slim app/views/layouts/ --delete
NoMethodError: undefined method `exists?' for File:Class
  Use --trace for backtrace.
```
追加するgemを`html2slim`から`html2slim-ruby3`へ変更することで対処できました。
[参考](https://qiita.com/aisaka1653/items/c250eb10767fb782c1c2)

# マージンの設定
本書ではマージンライトを設定する際にはbootstrapの`mr`クラスを使用しています。
[bootstrap5以降では記法が変わり](https://getbootstrap.jp/docs/5.0/utilities/spacing/)、`me`クラスを使用する必要があります。
レフト(`ml`)なら`ms`。
[参考](https://teratail.com/questions/332217)

![スクリーンショット 2024-06-11 9.43.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3671028/3107d0b8-2116-ea1e-454c-b0054368d8e5.png)
![スクリーンショット 2024-06-11 9.43.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3671028/19404f9f-f390-7e7e-a7c9-055e29501673.png)

# DELETEメソッドでのリクエスト
rails7では
```Slim:
link_to({name},{path},method: :delete)
```
の形でDELETEメソッドを呼ぶことができない。
以下に修正する必要あり。
```Slim:
link_to({name},{path},data: {turbo_method: :delete})
```
[参考](https://zenn.dev/jinku/articles/eb079fc44b6aee)

# リンクを踏んだ際のアラート表示
rails7では以下のようなリンクの記載だとアラートが表示されない。
```slim:
link_to({name},{path},data: {confirm: "アラートメッセージ"})
```
以下に修正する必要あり。
```slim:
link_to({name},{path},data: {turbo_confirm: "アラートメッセージ"})
```
[参考](https://hazm.jp/posts/Rails7%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8Bdata-confirm)
OpenRoamingのプロファイルインストールが上手くいかない

FirefoxからOpenRoamingのプロファイルをインストールしようとしてもうまく動かなかったが、ブラウザを変えれば上手く動いた。

Apple系ならSafari, AndroidならChromeから操作すると動いたのでメモ。
Ubuntuで日本語入力

Ubuntuで日本語入力を設定するには、以下の手順を実行する

## 1.必要なパッケージのインストール
まず、必要な日本語入力システム（例えば、MozcやFcitx）をインストールします。以下のコマンドを端末で実行します：

```
sudo apt update
sudo apt install fcitx-mozc
```

## 2.入力メソッドの設定
次に、入力メソッドを設定します。fcitxを使用するためには、fcitxを起動する必要があります。これを行うために、~/.xinputrcファイルを編集して以下の内容を追加します：

```
im-config -n fcitx
```

## 3.環境変数の設定
端末で以下のコマンドを実行して環境変数を設定します：

```
export GTK_IM_MODULE=fcitx
export QT_IM_MODULE=fcitx
export XMODIFIERS=@im=fcitx
```

## 4.再起動
すべての設定が完了したら、システムを再起動します。再起動後にfcitxが起動し、日本語入力が可能になります。

## 5.入力メソッドの切り替え
再起動後にデスクトップ右上のシステムトレイにfcitxのアイコンが表示されるはずです。アイコンをクリックして入力メソッドをMozcに切り替えます。

## まとめ
以上の手順を完了すれば、Ubuntuで日本語入力ができるようになります。
Ubuntuでcshを起動するための実行環境を整備する。

# １．Ubuntuのインストール
・VirtualBoxとUbuntuのOSをインストール
youtubeを参考にインストールした。
参考：[【Linux初心者向】Linux を試してみたいけど手軽な方法がない？ それ、Virtualbox で解決！](https://www.youtube.com/watch?v=Vk-3UhuSPjc&t=30s)

上記だけでは不便だと感じたため、以下を実施。
参考：[**画面をフルスクリーンに変更する方法**](https://qiita.com/takedon0909/items/e334da7b4c3d36b4d580)


参考：[**日本語入力の方法**](https://qiita.com/takedon0909/items/2d5e14b77fce9bbcb3c9)

# ２.実施すること
・README.mdの作成
・ディレクトリ作成

## ３．README.mdの作成
まずは、README.mdを作成する。
```
adm/adm[30]: cd ~
adm/adm[30]: pwd
/home/yuya
adm/adm[30]: touch README.md
adm/adm[30]: ls README.md
README.md
```
次に、README.mdを編集する。
```
adm/adm[30]: nano README.md 
```
README.mdの内容は以下のように記載しました。
個人で使用する場合は不要ですが、複数人で共有する場合は必要なファイルですね。

```
# Batch Processing Project

## 概要
このプロジェクトは、バッチ処理の勉強のために作成した。

## フォルダ構成
以下のようにディレクトリを構成しています：

```plaintext
batch/
├── bin/       # 実行可能ファイル
├── ctl/       # 制御ファイル
├── etc/       # 設定ファイル
├── out/       # 出力ファイル
│   ├── log/   # ログファイル
│   ├── snd/   # 送信ファイル
│   ├── rcv/   # 受信ファイル
│   └── tmp/   # 一時ファイル
├── script/    # バッチスクリプト
├── src/       # ソースコード
└── sql/       # SQLスクリプト
```
※余談ですが、sakuraなどのGUIに慣れているとnanoでの入力は難しいですね。
操作方法については以下を参考にしました。

参考：[nanoの使い方](https://utakamo.com/article/linux/editor/nano/index.html)
よく使うコマンドは
| 説明 | ショートカットキー |
|:-:|:-:|
|編集内容を保存する|ctrl + O|
|nanoを終了する|ctrl + X|
|文字列をカットする|ctrl + K|
|文字列をペーストする|ctrl + U|
|前回操作を取り消する|alt + U|
|文字列を検索する|ctrl + W|

## ４．ディレクトリの作成
上記、README.mdファイルのフォルダ構成に沿って、ディレクトリを作成します。

```sh:csh
mkdir -p batch etc batch/sql batch/script batch/bin batch/src batch/etc batch/ctl batch/out batch/out/log batch/out/snd batch/out/rcv batch/out/tmp
```
以下のように出力されました。

```
adm/adm[44]: ls -R
.:
bin  ctl  etc  out  script  sql  src
./bin:
./ctl:
./etc:
./out:
log  rcv  snd  tmp
./out/log:
./out/rcv:
./out/snd:
./out/tmp:
./script:
./sql:
./src:

```

## ５．まとめ
今回はcshとSQLを使用するため、このような構成にしたが、使用言語が増えると構成も柔軟に変更する必要がある。
次回はシェルの起動を標準化するため、キックシェルの作成実施する。

次回記事：[【csh】キックシェルの概要](https://qiita.com/takedon0909/items/27dc5e8e1908f75c4290)
直感的な操作性を考慮するのは実はすごく難しいんじゃないかという話

## はじめに
QAエンジニアをしているもんです
今回はプロダクトのことを考えすぎるあまり直感的な操作性を考慮しにくくなってしまった話を自戒の念も込めて記事にしてみました

## 仕様の決め方
仕様を決める時にはざっくりこんな感じで決めていくことが多いんじゃないかなと思います

1\. 要件定義
2\. MUST要件仕様
3\. WANT要件仕様（高）
4\. WANT要件仕様（中）
5\. WANT要件仕様（低）
6\. ...

## 直感的な操作性との関係性
機能開発時に直感的な操作をなるべく損なわずに便利な機能を盛り込むかはとても重要なことです

直感的な操作が出来ないプロダクトは、問い合わせを誘発したり、たとえ便利であっても利用までのハードルが上がりそもそも使ってもらえなくなったりします

ユーザーに喜んでもらうために一生懸命考えて実装した結果がこれでは悲しすぎます

私達はより良い価値提供を目指し日々開発しているプロダクトと向き合い、四六時中そのことを考えています
ですが、それゆえに直感的操作性について鈍感になっていってしまい、結果的に仕様を覚えてコツを掴めば便利な機能を実装してしまうのです

毎日プロダクトと向き合っている私達と違い、ユーザーは日々の生活のほんの一部でしかプロダクトと向き合うことはない為、時には機能が沢山ついていることよりも直感的に操作できることの方が良かったりします

## 超独断と偏見による代表例
私はこの機能性と直感的操作性のバランスが好きだなと思う製品はiPhoneです

発売初期のiPhoneはホーム画面の拡張も出来なかったし、ウィジェットもありませんでした

でも、めちゃくちゃ分かりやすい
全てのアプリは横スクロールしてたら絶対どこかにあるし、タップすれば起動し、ホームボタンを押せば閉じることが出来る

それに比べてAndroidはホーム画面のデザインも変えられるし、ウィジェットも使えます

でも、めちゃくちゃ分かりにくい
なんかいじっちゃってホーム画面のモードが切り替わってしまい戻し方は分からない。取ったアプリがどっか行っちゃってどこで起動すれば良いか分からない、、、などなど

当時、携帯の販売員をしていた機械音痴の私は、Androidの機能を覚えるのは辛かったですし、売れ行きもiPhoneが圧勝でした

2023年6月時点でもiPhoneのシェアは69.3％と驚異的シェア率を叩き出しています

[SHIFTASIA](https://shiftasia.com/ja/column/2023%E5%B9%B48%E6%9C%88%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%83%95%E3%82%A9%E3%83%B3os%E3%82%B7%E3%82%A7%E3%82%A2/#:~:text=%E6%97%A5%E6%9C%AC%E3%81%A7%E3%81%AF%E4%BE%9D%E7%84%B6%E3%81%A8%E3%81%97%E3%81%A6iOS%E3%81%8C,%E3%81%8C%E6%8B%A1%E5%A4%A7%E3%81%97%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82
 "日本とグローバルのスマホOSシェア")参照

## 解決策
私より遥かに頭もよく、知識や技術も豊富な方々が作ったスマートフォンですらそういったことに陥るのに、なんの対策もなしに乗り越えられるわけがない
そんな思いから解決策を考えてみました

方法としては下記などを複数組み合わせて計測するのが効果的だと考えます
・ユーザーからレビューをもらう
・そのプロダクト（チーム）外の人に実際に操作をしてもらい、意図がどれだけ伝わっているか確認する
・問い合わせの内容を集計し、傾向を探る


問い合わせの内容を集計するだけではそもそも使われていないだけかもしれないですし、ユーザー（社内のチーム外のメンバー）からレビューやフィードバックをもらうだけでは機能の利用頻度が測りにくく、優先度をつけにくいため、どれか１つではなく複数の方法をかけ合わせて分析することがとても大事です

課題さえわかればあとは改善するだけなので、フィードバック→改善のサイクルを回してくとより良いプロダクト開発になるはずです

## おわりに
日々プロダクトと向き合いすぎて、分からないことが分からない現象に陥ってしまい迷走中の方のお役に少しでも立てればという思いと、私自身まだまだ迷走中なので、良案やアドバイスが欲しいな〜という思いでこのテーマを書かせていただきました
インストールできてない奴

ドラッグ＆ドロップ出来んが？

https://robertjoosten.github.io/maya-module-manager/

https://unpyside.com/blog/2020/08/20/module-workflow/

https://3dnchu.com/archives/maya-module-manager/

モジュール形式でも出来んが？pipでインストールってこと？

https://kiwamiden.com/tools/amaterasu/install
「プレフィックス」と「サフィックス」


プレフィックスはよく聞くけどサフィックスは初耳だった。

# プレフィックス
クラス名の頭によくつける文字列で接頭辞ともいう。
こういう感じ
```
<div class="l-main">
```
この「l-」の部分がプレフィックス。

# サフィックス
プレフィックスの逆で最後につける文字列で接尾語のこと。
こういう感じ
```
<div class="l-main-info">
```
この「-info」がサフィックスらしい。
モディファイアもサフィックスなのかな。

今度ちゃんと調べる。
毎日ABC day17【c++】ABC329 A-C問題解説【ACコード付き】

# AtCoder Beginner Contest 329

https://atcoder.jp/contests/abc329

## A - Spread
与えられる文字列を1文字区切りで出力する。

```cpp
int main()
{
	string S;
	cin >> S;
	for (int i = 0; i< S.size(); i++)
	{
		if (i > 0) cout << " ";
		cout << S[i];
	}
	cout << endl;
	return 0;
}
```

## B - Next
$N$ 個の数字が与えられるので、2番目に大きな数を出力する。

```cpp
int main()
{
	int N;
	cin >> N;
	int A[109];
	int ans = 0;
	int top = 0;
	for (int i = 1; i <= N; i++)
	{
		cin >> A[i];
		if (A[i] > top)
		{
			ans = top;
			top = A[i];
		}
		else if (A[i] > ans && A[i] < top)
		{
			ans = A[i];
		}
	}
	cout << ans << endl;
	return 0;
}
```

## C - Count xxx
与えられる文字列 $S$　の部分文字列かつ、1つのアルファベットのみからなるものの数を数えよ。

ただし、与えられる文字列は全てアルファベット小文字からなる。

```cpp
int main()
{
	int N;
	cin >> N;
	string S;
	cin >> S;
	// アルファベットごとに何通り存在するかカウント
	int alpha[26];
	char current_alpha = S[0];
	int current_num = 1;
	alpha[current_alpha - 'a'] = 1;
	for (int i = 1; i < N; i++)
	{
		if (current_alpha != S[i])
		{
			alpha[current_alpha - 'a'] = max(alpha[current_alpha - 'a'], current_num);
			current_num = 0;
			current_alpha = S[i];
		}
		current_num++;
		alpha[current_alpha - 'a'] = max(alpha[current_alpha - 'a'], current_num);
	}

	// 総通り数を合計して出力
	long long ans = 0;
	for (int i = 0; i < 26; i++) ans += alpha[i];
	cout << ans << endl;
	return 0;
}
```
Pythonで数値計算を効率化する Part3

前回の記事に続いて、今回はさらに実用的なNumPyの使い方を紹介します。
データ解析でよく使用される応用的な操作について詳しく説明します。

#### 応用的なNumPyの操作

##### 1. 配列の結合と分割

データを扱う際には、複数の配列を結合したり、一つの配列を分割したりすることがよくあります。

```python
import numpy as np

# 配列の結合
a = np.array([1, 2, 3])
b = np.array([4, 5, 6])
combined = np.concatenate((a, b))
print(f"結合された配列: {combined}")  # 結合された配列: [1 2 3 4 5 6]

# 2次元配列の結合
c = np.array([[1, 2], [3, 4]])
d = np.array([[5, 6], [7, 8]])
combined_2d = np.vstack((c, d))
print(f"結合された2次元配列:\n{combined_2d}")
# 結合された2次元配列:
# [[1 2]
#  [3 4]
#  [5 6]
#  [7 8]]

# 配列の分割
split_array = np.split(combined, 3)
print(f"分割された配列: {split_array}")
# 分割された配列: [array([1, 2]), array([3, 4]), array([5, 6])]
```

##### 2. 配列の変形

データの形状を変更することは、解析の準備段階で頻繁に行われます。

```python
# 配列のリシェイプ
e = np.array([[1, 2, 3], [4, 5, 6]])
reshaped = e.reshape((3, 2))
print(f"リシェイプされた配列:\n{reshaped}")
# リシェイプされた配列:
# [[1 2]
#  [3 4]
#  [5 6]]

# フラット化
flattened = e.flatten()
print(f"フラット化された配列: {flattened}")
# フラット化された配列: [1 2 3 4 5 6]
```

##### 3. ブロードキャスト

異なる形状の配列間での演算も可能です。

```python
# サンプルデータ
f = np.array([1, 2, 3])
g = np.array([[0], [1], [2]])

# ブロードキャストによる演算
result = f + g
print(f"ブロードキャストによる演算結果:\n{result}")
# ブロードキャストによる演算結果:
# [[1 2 3]
#  [2 3 4]
#  [3 4 5]]
```

##### 4. 条件による選択

データの中から条件に基づいて要素を選択することも、NumPyを使うと簡単です。

```python
# サンプルデータ
h = np.array([1, 2, 3, 4, 5, 6])

# 条件による選択
selected = h[h > 3]
print(f"条件に合致した要素: {selected}")
# 条件に合致した要素: [4 5 6]
```

##### 5. 高度なインデックス操作

NumPyは柔軟なインデックス操作をサポートしています。

```python
# サンプルデータ
i = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])

# 特定の行や列を選択
row = i[1, :]
print(f"2行目の要素: {row}")
# 2行目の要素: [4 5 6]

column = i[:, 1]
print(f"2列目の要素: {column}")
# 2列目の要素: [2 5 8]

# 複数の行や列を選択
subarray = i[0:2, 1:3]
print(f"部分配列:\n{subarray}")
# 部分配列:
# [[2 3]
#  [5 6]]
```

##### 6. ランダムサンプルの生成

ランダムなサンプルを生成することは、シミュレーションや統計解析でよく使用されます。

```python
# ランダムな整数の配列を生成
random_integers = np.random.randint(0, 10, size=(3, 3))
print(f"ランダムな整数の配列:\n{random_integers}")
# ランダムな整数の配列:
# [[4 9 0]
#  [1 5 7]
#  [6 3 2]]

# ランダムな浮動小数点数の配列を生成
random_floats = np.random.random((3, 3))
print(f"ランダムな浮動小数点数の配列:\n{random_floats}")
# ランダムな浮動小数点数の配列:
# [[0.56792387 0.27218365 0.45603387]
#  [0.94244895 0.18355667 0.78373165]
#  [0.62866469 0.49440931 0.22756961]]

# 正規分布に従うランダムな数の配列を生成
random_normal = np.random.randn(3, 3)
print(f"正規分布に従うランダムな数の配列:\n{random_normal}")
# 正規分布に従うランダムな数の配列:
# [[ 0.75388898 -0.58065735 -0.45284685]
#  [-1.45413148 -0.12491374 -1.40538161]
#  [ 1.4576425  -0.19432105  1.12135873]]
```

以上

---

https://qiita.com/benjamin1gou/items/9b24deb7d62013177aca
DBデータデリート

**　意図しないデータの削除経験（QiitaEngineerFesta2024）**

しくじりエンジニアとして、あるある（？）のデータ削除経験を投稿します。


・目次
1.事象
2.原因
3.解決方法
4.対策

<br>
<br>

**1.事象**

初歩的なミスですが、where文を付けずにdeleteを実行してしまいました。。。

・本来実行すべきクエリ
```
DELETE FROM [テーブル名] WHERE [カラム] = ''; --条件一致データのみ削除
```

・誤ったクエリ
```
DELETE FROM [テーブル名] ; --全件削除
```

<br>
<br>


**2.原因**

簡潔にまとめると確認不足ですが、詳しく原因分析を行います。

▼技術的要因
　・バックアップの不足
　・リカバリメカニズムの不備（トランザクションログの管理）
 
▼ヒューマンエラー
　・確認不足
　・誤ったSQLクエリ

▼プロセス・手順の問題
　・手順の欠如
 

<br>
<br>


**3.解決方法**

バックアップを実行しておらず、自動コミット設定だった為データの復旧ができず、
1からデータを作り直しました。。



<br>
<br>


**4.対策**

▼技術的要因
　・バックアップの不足
 　→DBバックアップを定期的に行い、復元可能にする。
  　また、復元手順を定期的に確認しておく。
   
　・リカバリメカニズムの不備（トランザクションログの管理）
 　→トランザクションログを管理、確認できるようにしログから復元可能な状態にする。
 　→クエリ実行時にトランザクションを記録し、自動commitを使用しない。
 
▼ヒューマンエラー
　・確認不足
 　→事故意識の欠如。　改めて意識して作業を行う。
  
  ・誤ったSQLクエリ
  →DELETE文作成、実行時の注意点を理解する。（WHERE文を先に書く、など。）


▼プロセス・手順の問題
　・手順の欠如
　　→DELETE、UPDATE等のデータ更新時は指差し確認を行なう。 


<br>
<br>
<br>

以上
Goのdefer実行タイミング

慣れている人からすると当たり前なんですが、冷静に考えると間違えそうだったので、備忘録。

## deferのタイミング
```go: コード
func foo(str string) {
    fmt.Println(str)
}

func main() {
    str := "でぃふぁー"
    defer foo(str)

    str = str + "ぷりんと"
}
```

さて、この時表示する結果はなんでしょうか。

1. でぃふぁー
2. でぃふぁーぷりんと
3. ぷりんと
4. 空文字

正解は

```go: 結果
でぃふぁー
```

ですね。

defer関数の引数は実際の呼び出しが行われた時ではなく、deferステートメントが実行されたときに評価されます。

## return時はどうなるか

ではreturnがある場合先なのか、後なのかどちらでしょう。

```go: コード
func hoge() string {
	str := "でぃふぁー"
    defer fuga()
	fmt.Println("りたーんまえ！")
    return str
}

func fuga() {
    fmt.Println("いつかな？")
}

func main() {
	fmt.Println(hoge())
}

```

```go: 結果
りたーんまえ！
いつかな？
でぃふぁー
```
コードの並び順的には「いつかな？」→「りたーんまえ！」→「でぃふぁー」ですが、出力結果は違いますね。

deferで出力する「いつかな？」はreturnより先に実行されているのが確認できました。

## おまけ
初心忘るべからずということで↓のXアカウントの方をお勧めします。簡単なコードですが「あれ、そういえば...」って感じで現状の自分の答え合わせとしてPostを眺めてみるのは面白いと思います。

https://twitter.com/he3torbarbossa
BubbleでStripeのwebhookのやり方

何回やっても忘れるのでメモ

1. Bubble.io の Setting > api "Enable Workflow API and backend workflow"
![スクリーンショット 2024-04-24 16.27.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/e903271d-ce93-e5d0-d459-cc96f67bcc82.png)
1. Homeの隣、pageを切り替える部分をクリック。一番下に"Backend workflow"
1. Click here... から　"New API workflow"
1. 適当にnameを入れて、parameter definition は　"Detect request data"
1. "Detect data"をおすと、initialize するためのURLがでてくるのでコピー
![スクリーンショット 2024-04-24 16.35.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/95af709b-3803-6d4d-0119-f12668aa408e.png)![スクリーンショット 2024-04-24 16.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/eafa17a8-f8b6-65d4-12e7-bfc64e482c3c.png)


1. StripeのDevelopers > Webhooks > Add endpoint![スクリーンショット 2024-06-11 14.05.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/22c6b0f4-4060-a611-cb4b-e49ad7b0cc42.png)

1. Endpoint URLに先ほどコピーしたinitializeするためのURLをペースト
1. select event listen to から受け取りたいイベントを選択 > add endpoint
[Webhookイベント一覧はこちら](https://docs.stripe.com/cli/trigger)　![スクリーンショット 2024-06-12 8.25.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/d58c7332-69e9-d32c-012e-37713fd7742c.png)

1. [ローカル環境からテスト](https://dashboard.stripe.com/webhooks/create?endpoint_location=local)することもできますが、めんどうなので、受け取りたいイベントが発生する操作をする。ユーザーがサブスクキャンセルする　など
1. Bubble側を開くとデータが飛んできているのが確認できる。型を確認して　Save![スクリーンショット 2024-04-26 10.20.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/47236/6967e22a-99c7-6401-5a83-2dc99300ec73.png)
1. Stripeに戻って、対象のendpointをクリック、右端の[...]からUpdate details
1. Endpoint URL の　最後の　/initializeを削除して保存


以上！
[備忘録]　読んだネットの記事 (FA業界) ver.2

# 備忘録
"オークラが協働ロボットを使ったパレタイジングシステムを発売、URと提携"
https://monoist.itmedia.co.jp/mn/articles/2406/05/news085.html

[備忘録]
- 床に赤色で書かれている停止エリアと黄色で書かれている減速エリア上にそれぞれ人間が立った場合，パレタイジングロボットが同期して停止または減速を行う
- 従来では重量物を素早くさばくことが要求されていた
    - 巨大かつ高速で動作するため，非常停止ボタンを押しても慣性で動いていた
    - 安全性の観点から広いエリアを柵で囲まなければならない
- 昨今では軽めの可搬重量だが高速ではないかつ安全に使える協働ロボットが注目されている
    - 省スペースで導入できる点が好評価
    - レーザーセンサーなどを活用することで侵入防止用の柵は不要


"SUBARUの工場でMujinのバラ積みピッキングロボ導入、鍛造粗材の投入作業を自動化"
https://monoist.itmedia.co.jp/mn/articles/2405/16/news089.html

[備忘録]
- バラ積み状態のワークのピッキングをティーチング作業なしで実現
- バラ積みピッキング実行中にセンサーを活用した異常検知も可能
    - 3Dビジョンによる画像処理
    - ティーチングレス
    - 搬送中にセンサーで２個取りを検知：保全
- ロボットセルの設計時にはデジタルツイン環境でモーションプランニングによるシミュレーションを遂行
- バラ積みピッキングは立ち上げやトラブル時の原因把握が困難
    - コントローラに記録された稼働ログの確認が可能


"“こんな場所も手が届く”手術ロボットなどで活用を目指す椿本の極小チェーン
FOOMA JAPAN 2024"
https://monoist.itmedia.co.jp/mn/articles/2406/07/news086.html

[備忘録]
- ロボットハンドが屈曲などをしながら，ビンの細かい口にぶつからず小さなボールを出し入れする
- 手術支援ロボットのハンド部分での活用などを想定
- 異物混入を発見しやすいように青色仕様に設定

"安川電機が自律ロボットで下膳作業を自動化、食品仕様のスカラロボットも"
https://monoist.itmedia.co.jp/mn/articles/2406/11/news087.html

[備忘録]
- 状況に合わせて自ら計画，判断，作業を完結させる自律的な動作が可能な機能をロボットに搭載
- コントローラに周囲の環境の認識，判断処理およびセンサーから得られた周囲の位置情報を基に動作計画を立てて実行
    - コントローラの開発環境をオープン
- 安川のスカラロボットはZ軸を先端ではなくベースの方に持たせてある
    - Z軸からの異物混入を防止するため
    - 先端の回転軸は特殊ラビリンス構造
        - 水などの内部への侵入やネジなどの外部への落下を防ぐ
    - システムとして提供

"三菱電機の標準化ロボットセルがAI外観検査、ラムネの割れなどを検出"
https://monoist.itmedia.co.jp/mn/articles/2406/10/news082.html

[備忘録]
- ロボットと部品供給，トレイ排出部などをモジュール化したセルを活用
- 生産ラインの構築や品種変更，セルの追加や再配置が容易
- ネジ締めといった工程に合わせてアプリケーションの変更が可能
- それぞれのセルを繋ぎ合わせることも容易
- 良品学習の場合，10sでAIの学習が完了
- ラムネ菓子を番重の中で収めるシートの深さが足りず，番重を動かしたら菓子がずれることもシミュレーションで判明
誰が落としたのかを確認したいだけだった

# 概要

https://qiita.com/official-events/fd39ed8cc0dcc9829621

こんな企画やられてたので、そんなイベントあったかな？って思ったけどいっぱいあったのでその中の一つをサクッと書き出してみる


# やりたかったこと

- サーバをリモートで管理するチームのメンバーだったとき、モニタリングしているととある1台のサーバが再起動したようなグラフになっていた
- サーバへログインして、コマンド履歴を確認し、`shutdown`コマンドが実行されていないか確認したかった


# やったこと

```bash
$ history | shutdown
```

# 本当にやりたかったこと

```bash
$ history | grep shutdown
```

勢い余った・・・

# 結果

- 無事再起動した
    - 起動しなかったらサーバ管理者へお願いしてデータセンターへダッシュしてもらうところだった
- 上司には怒られた
    - 幸いにも社内用サーバだったのでサービス影響はなかった

# 対策

- rootユーザーだったのがそもそも感あるので、管理者権限を与えていないユーザーを用意した
- 対策ではないが、これを機にLinuxを勉強した記憶があります
システム運用を1年やってみての感想

# はじめに

引き継いだプロジェクトでシステムの運用を経験して一年が経つので、開発視点とプロジェクト視点で所感をまとめてみたいと思います。

:::note warn
あくまで個人の所感になります。
:::

# 開発視点での所感(学び・今後に生かしたいこと)
- <font color="red">**短期より長期目線での開発を心掛けたい**</font>
開発速度と品質のトレードオフになるのかなと考えています。
速度重視でシステムを作ったものの「テストなし」「型なし」「多数のコメントアウト」「メソッドやコンポーネントが共通化されていない」という状態だと、後から発生する工数が計り知れないなと感じました。

具体的に発生した工数
- 型定義があれば未然に防げていたバグ対応
- テストがあれば未然に防げていたバグ対応
- 書き方が統一されていないCSSの修正
- テスト導入に向けた一部リファクタリング
- テスト作成


今後は以下の点を意識して開発に取り組みたいです。
- 型定義の導入
- コンポーネントライブラリの導入
- テスト駆動開発


速度と品質のバランスを上手く調整して開発したいなと考えさせられる一年でした。


# プロジェクト視点での所感(学び・今後に生かしたいこと)
- <font color="red">**やること・やらないことを予め決めておく**</font>
今回のプロジェクトでシステムを開発した目的が「顧客(toB)の潜在ニーズを抽出し、受託案件につなげること」でした。
そのため開発速度を重視してシステムを開発し、いち早く顧客に利用してもらい、ニーズを抽出したかったのですが事はトントン拍子に運びませんでした。

実際に顧客からいただいたフィードバックの一例(ぼかしています)

---

A社「うちは社員数多いので権限を分けられる機能がほしいです。そしたら導入できそうです。」

B社「○○AIの最新モデルを使いたいです。」

C社「この画面のここを改修してほしいです。使いづらくって…」

---

プロジェクトの目的である「ニーズ抽出」以前に「システムの使い勝手」が課題となっていました。
使い勝手は顧客によってバラバラです。他の顧客でも上がっている要望から優先度をつけて対応することにしていましたが、あくまで「使い勝手」を良くするための対応であり「ニーズ抽出」を直接支援するための対応ではありません。(使い勝手が良くなることでニーズ抽出しやすくなるという相関はあるかもしれませんが…！)
そして「使い勝手」を良くするための対応には、後から発見されたバグ対応も含まれています。

これらを全て対応するとプロジェクトの目的達成に対して後手になってしまうため、やること・やらないことは明確にしておく必要があるな、と感じました。

<font color="blue">**ここからはプロジェクトの大まかな情報や業務内容について記載します。**</font>

## プロジェクト情報
- 前の担当者が突貫で開発し、システムとしてはほぼ出来上がった状態
- 引き継いだメンバーは私含め2名。システムの技術スタックに触れたことがあったため。(一時期は3,4名でたいお)
- システムを顧客に利用してもらい、潜在ニーズを探って受託案件に繋げたい！


## 業務内容
- システムの改修や機能開発
- システムの運用 ←New


## 運用面でやったこと

- 顧客環境の構築・更新・削除
  - 依頼を受けたら環境を構築し、システム設定・ユーザ登録などを行う

- バグ改修や機能開発 
  - 優先度つけて対応

- ドキュメント整備
  - 利用マニュアルのたたき台を作成  
  - 環境構築の手順書を作成
  - 環境情報の一元化 
  -  リースノートの作成

- 社内での調整
  - 営業サイドからの質問対応や環境更新日程の調整など 


# おわりに
運用も大変だと感じましたが、システムを長く使ってもらうには必要不可欠な要素だと思いますので考えやノウハウを身に着けていきたいです。
私がボイパしてる!?【自分に歌わせたい①：OnSay.ai】

## 生成AIに歌わせてもらう
こんにちは、歌うのが好きな者です。

AIが歌っている動画を最近よく見かけますが、どれもクオリティが高くて驚きます。

歌いたいけどなかなか自宅では歌えない……ということで、生成AIに自分の声を学習させて、代わりに歌ってもらおうと思います。

## 今回の使用ツール

今回用いたのは「OnSay.ai（β版）」です。
https://onsay.ai/

PCだけでなくスマホでも行えるため、誰でも気軽に体験できます。

>モデルがあれば、
>ボイパも第九もなんでも歌える！

またOnAay.aiの面白い特徴は、**歌だけではなく楽器にも対応しているところです。**

どういうこと？と思いますが、早速試してみましょう。

## 音声モデルの作成
音声モデルを作成するため、用意されたセリフをそれぞれ録音していきます。
パターンは全てで**100種類**、なかなか骨の折れる作業ではありました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/9169585e-b423-be56-0731-730b4940f66e.png)
こちらが最初の数パターン。
セリフを用いてツールの説明をしているのが面白いです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/180f9fcc-0a2b-1825-1414-26f14eecb673.png)
基本はこのような形で、多種多様なセリフを読みました。
ただ音のパターンを録音するのではないところが飽きさせなくてよいと感じます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/04ed8722-634d-1c12-d2b2-ea26c2a3a6d3.png)
後半になると「この音が欲しいんだろうな……。」と感じるセリフもありました。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/0d5d0f5d-a7a0-eba6-23a4-70b3333e175e.png)
最後はこちら、公式サイトのキャッチコピーで終わります。
個人的には粋だと感じるところが多く、録音過程も面白かったです。

## 実践！
作成した音声モデルを用いて、AIボイスを作ってみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/40b25b98-2994-97aa-dc88-e136272e929e.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/bd91841d-d13d-817c-4ce2-5a15cb2b0fda.png)
現在選択できるのはこちらの6種類です。
歌と楽器、それぞれ3種ずつになっています。

選択肢が少ないと感じてしまいますがこちらはβ版なうえ無料なので、今後発展して増えるのかもしれません。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3518925/f7ab3c73-a486-6f97-dab7-7c82438a502a.png)
完成したAIボイスはダウンロードもできます。zipファイルで、解凍すると音声形式と動画形式のファイルが入っていました。


## 感想
歌の中だと、結婚行進曲（女声）が一番「自分の声だ！」となりました。
読み上げたセリフを基に作成した音声モデルなので、歌っている声というよりは地声に近い感じです。

楽器3種は正直よくわかりませんでしたね……。
（ボイパもサンプルほど上手くいきませんでした。）

これは声域と選択肢の音域の差による違和感だと思います。リアルさには欠けますが、何らかの機械音声を聴いている感覚になるので、自分がモデルだと思うと面白かったです。
セリフを録音しただけでボイパや楽器風の音声が出来上がるのは、素人ながらにすごいなと感じました。

今後の発展にも期待です！
また他の生成AIにもチャレンジしたいと思います。

## 補遺
本当は音声か動画を埋め込みたかったのですが、方法が見つかりませんでした。
（Youtubeに非公開で投稿する手も考えましたが、ちょっと気が乗らず……。）

方法があればご教示いただきたいです。