OmniAICreator/Qiita-1.07M huggingface dataset:
Anaconda仮想環境の環境変数設定

# 目的
Anacondaの仮想環境を立ち上げたときに自動で環境変数`PYTHONPATH`を設定します。
その他の環境変数の設定も同様に可能です。

# 背景
以下のようなディレクトリ構成で開発を行っていました。
```
project/
   ├ modules/
   │  ├ module1.py
   │  └ module2.py
　 ├ sub1/
   │  ├ notebook1.ipynb
   │  └ script1.py
　 └ sub2/
      ├ notebook2.ipynb
      └ script2.py 
```
`project/modules/`以下には、複数のサブディレクトリで共通して使いたい自作モジュールを配置しています。
このとき、例えば`project/sub1/script1.py`から`module1`をインポートする場合、以下のようにモジュール検索パスを追加する必要がありました。
```python:script1.py
import sys
sys.path.append("..")

from modules import module1
```
毎回これを書くのは面倒なので、Anacondaの仮想環境を立ち上げた際に、自動的に環境変数`PYTHONPATH`を設定するようにしました。

# 仮想環境での環境変数の設定
[Condaユーザーガイド (Saving environment variables)](https://conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html#saving-environment-variables)に詳しい説明があります。

対象の仮想環境ディレクトリに`etc/conda/activate.d/`と`etc/conda/deactivate.d/`という二つのディレクトリを作成します。
`activate.d/`には環境起動時に実行するスクリプトを、`deactivate.d/`には環境終了時に実行するスクリプトを配置します。スクリプトは[こちら](https://github.com/KodaiS/conda-set-env-vars)にあります。

```bash:activate.d/set_pythonpath.sh
#!/bin/bash

_additional_path="/path/to/your/modules"

if [ -z "$PYTHONPATH" ]; then
    export PYTHONPATH="$_additional_path"
else
    export OLD_PYTHONPATH="$PYTHONPATH"
    if [[ ":$PYTHONPATH:" != *":$_additional_path:"* ]]; then
        export PYTHONPATH="$PYTHONPATH:$_additional_path"
    fi
fi
```
```bash:deactivate.d/unset_pythonpath.sh
#!/bin/bash

if [ -n "$OLD_PYTHONPATH" ]; then
    export PYTHONPATH="$OLD_PYTHONPATH"
    unset OLD_PYTHONPATH
else
    unset PYTHONPATH
fi
```
これらを配置した状態で`conda activate env`を実行すると`PYTHONPATH`が設定され、`conda deactivate`を実行すると`PYTHONPATH`は元に戻ります。

# VSCodeのJupyter拡張機能を使う場合
ターミナルで`PYTHONPATH`を設定していても、VSCodeのJupyter拡張機能を使ってノートブックを実行した場合には反映されません。これについてはGithub Issueがありました。
[$PYTHONPATH in notebook is different than in terminal #9436](https://github.com/microsoft/vscode-jupyter/issues/9436)

Issueにあるように、VSCodeのJupyter拡張機能を使う場合にはワークスペースディレクトリに`.env`ファイルを配置しましょう。自動的に`PYTHONPATH`が設定されます。
```:.env
PYTHONPATH=/path/to/your/modules
```
【Swift】割り算の余りを求めたい

# はじめに
ちょー初歩的なことなんですけど、知らなくて焦ったことがあったので記事にしておきます。

# 何が起きたのか
私は割り算のあまりは`%`で求められると思っていたのですが、こんなエラーが発生しました。

```
'%' is unavailable: For floating point numbers use truncatingRemainder instead
```

あれ、`%`って使えなくなったの？って思ったんですが違いました。

`%`が使えるのはIntだけみたいです。

私はそれを知りませんでした。

では、DoubleやFloatなどの浮動小数点型ではどのように余りを求めるのでしょうか？

# 実装
### Int
```swift
// ❌
func calcIntRemainder1(dividend: Int, divisor: Int) -> Int {
    return dividend.remainder(dividingBy: divisor)
}
// ✅
func calcIntRemainder2(dividend: Int, divisor: Int) -> Int {
    return dividend % divisor
}
```

### Double
```swift
// ✅
func calcDoubleRemainder1(dividend: Double, divisor: Double) -> Double {
    return dividend.remainder(dividingBy: divisor)
}

// ❌
func calcDoubleRemainder2(dividend: Double, divisor: Double) -> Double {
    return dividend % divisor
}
```

### Float
```swift
// ✅
func calcFloatRemainder1(dividend: Float, divisor: Float) -> Float {
    return dividend.remainder(dividingBy: divisor)
}

// ❌
func calcFloatRemainder2(dividend: Float, divisor: Float) -> Float {
    return dividend % divisor
}
```

# おわり
多分初歩的なことなので、今回覚えられてよかったです。
【ChatGPT】箇条書きから文章作成

何の文章かによって、制約条件の内容を変えると精度があがると思う。

# プロンプト
```
#指示
あなたはプロのwebライターです。
#入力をもとに、#制約条件に則って最高の文章を作成してください。

#制約条件
・文字数は250文字〜300文字
・専門用語は使わず、分かりやすい内容にすること
・漢字、ひらがな、カタカナの割合を2:7:1にすること
・#入力から想定される読者の立場に立ち、足りない情報は追加すること

#入力
・文章に入れたい情報
```

# 利用例

## 入力したプロンプト
```

#指示
あなたはプロのwebライターです。
#入力をもとに、#制約条件に則って最高の文章を作成してください。

#制約条件
・文字数は250文字〜300文字
・専門用語は使わず、分かりやすい内容にすること
・漢字、ひらがな、カタカナの割合を2:7:1にすること
・#入力から想定される読者の立場に立ち、足りない情報は追加すること

#入力
・冷蔵庫には、玉ねぎ1個、にんじん1本
・カレーを作るか、肉じゃがを作るか迷っている
・献立に迷ったら、レシピ検索アプリ「コンダテ」がおすすめ
```

## レスポンス（GPT-3.5）
```
冷蔵庫には、玉ねぎ1個とにんじん1本があります。
カレーを作るか、肉じゃがを作るか迷っているなら、献立に迷った時に便利なレシピ検索アプリ「コンダテ」を利用すると良いでしょう。
カレーなら玉ねぎとにんじんが使えますし、肉じゃがも玉ねぎとにんじんが必要です。冷蔵庫の材料を有効活用できますね。
```

## レスポンス（GPT-4）
```
冷蔵庫を開けたら、玉ねぎとにんじんだけ。カレーや肉じゃが、どっちを作ろうか迷っちゃいますよね。
そんな時は、「コンダテ」というレシピ検索アプリがとっても便利です。このアプリを使えば、手持ちの材料で作れる料理がパッと見つかります。
冷蔵庫の中身が少なくても、おいしい食事を作るヒントが得られるんです。
カレーにするか、肉じゃがにするか、それとも全く違う料理に挑戦するか、コンダテで楽しく決めましょう。
```
Rail6でJavascriptを書き換えてもWebpackerが動いてくれない

Javascriptファイルに変更を加えても
```ターミナル
[webpacker] everything's up-to-date. nothing to do
```
と出力されて、反映されないというエラーが起きた・・・
しかし、デプロイ先ではちゃんと反映されています。
謎です

# 自分のローカル環境とdocker環境のみで起きた
dockerなしのローカル環境と、docker-composeでbuildしたコンテナーでこの謎現象は起きました。色々調べましたが、そもそもエラーメッセージが出ないので解決しようがありません。コードに原因があるのか、私のパソコンに原因があるのでしょうか？？

# クラウドIDEでgit cloneしてみる
クラウドIDEであるcloud9で、同じリポジトリからgit cloneしてみます。すると、ちゃんとJavascriptファイルの変更は反映されています。このことから、私のパソコンに原因があるのではないかと考えました

# 解決策
そして考えた解決策は、一旦ローカルのアプリを削除し、再びgit cloneしました
```コマンド
$ rm rf アプリ名
```
Railsアプリを消して、、、
```
$ git clone リモートリポジトリ
```
git cloneします。
そして、Javascriptファイルを変更すると
```
web-1  | [Webpacker] Compiled all packs in /アプリ名/public/packs
```
上手くいきました！！

ネットで調べても色々対策してもwebpackerのエラーが解決しないときは参考にしてみてください。
VimのPathを通そうとして少し戸惑ったこと&対処法

## 概要
- vimをためしてみたくなった
- Pathが通らなくて少し戸惑った

## 状況と対処法
vimを窓の杜から入れた

https://forest.watch.impress.co.jp/library/software/vim/

どうせなら、cmdでも触れるようにしたかった。
Pathをこれにしたがって、やったら通らなかった。

https://qiita.com/Futo_Horio/items/21456f8acbad3c6bb442

おかしかったので、Pathを見に行くと、vim.exeは`C:\Program Files\Vim\vim91`の下にあった。
Pathを正しくしたら、vimがcmdで反応するようになった

## まとめ
こぴぺ、だめ、絶対
booksmileの自動tab

バイト先で見るための投稿。商品コードを入力した後にtabキーが自動入力されないページがあるが、開発者ツールで以下のコードを実行すれば改善する。
```tab.js
document.addEventListener('input', function(e) {
    var input = e.target;
    if (input.tagName === 'INPUT' && input.type === 'text' && input.value.length === 13) {
        var formInputs = document.querySelectorAll('input[type="text"]');
        var currentIndex = Array.prototype.indexOf.call(formInputs, input);
        if (currentIndex < formInputs.length - 1) {
            formInputs[currentIndex + 1].focus(); 
        }
    }
});
```
技育CAMPハッカソンに初参加した感想

# はじめに
こんにちは！Tayuです。
今回技育CAMPマンスリーハッカソンvol.14に初めて参加した感想を書きます。

# 今回作ったもの
準備期間1週間で、即席のチームメンバーと掲示板webアプリを作成しました。

井戸端会議のように知らない人と話し、抜けたい時に抜けれるweb掲示板です。

### 制作物
https://id-bata-webapp.vercel.app

### システム構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3543034/ae9c4359-5a9c-1ea5-ca3a-6499fd83726c.png)

私はバックエンドのDjangoとREST Frameworkを使ったAPI取得の部分を担当しました。

### 技術的挑戦
全部。REST APIもdockerでの環境構築もまともにやったのは初めての経験でした、

# 感想
結論から言うとめちゃくちゃ楽しかったです。

まともなチーム開発経験がほとんどなかった私にとって、Githubでリポジトリを共有したり、Dockerで開発メンバーとの環境差分をなくす、など、知識はあっても実際にやったことがなかった経験をすることができたのはめちゃくちゃ貴重でした。

また、個人的に憧れていた「チームメンバーからGithubのレビューでLGTMをもらう。」という目標も達成できたので良かったです。

今回は受賞とまではいきませんでしたが、初めての経験ばかりで貴重な1週間でした。

# 反省
楽しかった半面、心残りもたくさんあります。

具体的には、

・デプロイまではいけたけど、実装したかった機能を全然達成できなかった

・フロントへの理解が浅かったせいで、担当のメンバ－に任せっきりになってしまった

# 最後に
今まで避けてきたフロントエンドを学ぶ必要があるな...と感じました。vol.14自体は終わりましたが、next.jsとtypescriptを勉強してまともなサービスにまで持っていきたいと思ってます。

次回も参加予定なので、今回のリベンジも含めて、賞を狙いにいきたいと思います！
ターミナルからコマンドでVSCodeを起動する

## ターミナルからVScodeを起動するコマンド
```
$ code
```
(現在いるディレクトリで開く)
```
$ code .
```
(特定のファイルを開く)
```
$ code ファイル名
```
## ターミナルからVScodeを起動できない場合
1. VSCode を起動する
2. 「command＋shift＋P」でコマンドパレットを開く
3. コマンドパレットの「>」に続いて「shell」を入力
4. 「シェル コマンド:PATH内に'code'コマンドをインストールします」をクリック
![VS code コマンド導入.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3694748/24ab036b-b5f2-8d33-d621-5ceb1185e1f9.png)
WEBアプリケーションに おけるビット演算の活用法

# はじめに

ビット演算は学生時代に勉強したものの、現場で使う機会がほとんどなく、活用法についてイマイチ分からなかった過去があります。

僕と同じように活用法について悩んでいる方の一助になればと思い、実際の活用法についてまとめました。
※社内勉強会で作成したスライドをほぼんど流用していますので、簡易的なものになっていますがご了承ください。

---

# ビット演算とは？

こんな感じのやつで、ITパスポートや学生の時とかに習うやつ。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1671245/2432f3c8-67ef-68cc-6a04-6feaff067fc2.png)

引用元：https://ameblo.jp/karin-koron-kichi/entry-12633595228.html

---

# 実際のビット演算

2進数に変換すると分かりやすい。

13は1101　3は0011

* AND演算は両方1なら1になるので、1101 AND 0011 == 0001
* OR演算はいずれかが1なら1になるので、1101 OR 0011 == 1111
* XOR演算は両方1なら0になるので、1101 XOR 0011 == 1110

---

# どういう時に使えば良いか分からない

実際に勉強したは良いものの、イマイチどこで使えば良いか分からない…。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1671245/ced4c937-26a8-6e2c-d6a4-e365498c5283.png)

---

# 役に立った使い方

* 祝日含めた曜日フラグ
* 1バイトでフラグを管
* 権限(認可)管理フラグ
※いずれもフラグ管理で力を発揮した。

---

# 祝日含めた曜日管理(bit演算無しVer)

要件
* 曜日、**祝日**によって表示内容が切り替わるシステム
* 管理者は日、月、火、水、木、金、土、祝のチェックボックスで設定可能

DBに曜日、祝日フラグカラムを用意。
sun、mon、tue、wed、thu、fri、sat、holiday

**チェックボックス表示の処理時**
SELECT文で各カラムを取得し、配列に入れて、表示。
**カラムが多くなってしまい配列に入れてあげたりして処理も面倒。**

---

# 祝日含めた曜日管理(bit演算有りVer)

DBにweekというカラムにbit型でフラグを格納。

日月火水木金土祝 = 00000000
レイアウトAは月曜〜金曜：01111100
レイアウトBは土日祝日：10000011

**チェックボックス表示の処理時**
SELECT文でweekカラムを取得し、forループ内でシフト演算(1を起点に左シフト)を活用して表示。
**1個のカラムで制御できて配列に入れずとも処理ができる！**

---

# 1バイトでフラグを管理(bit演算無しVer)

要件
* ゲームのマッチングサーバ側の処理でデータ通信を極力抑えないとNG
* 新たにパラメータを追加するとクライアント側も修正が増えるので出来れば既存パラメータ内で

**既存パラメータ(例)**
user_name, user_level, flg, matching_state_date_time, etc…

バッファも無く新たにパラメータを追加しては駄目って無理じゃね？
どうすれば…。

---

# 1バイトでフラグを管理(bit演算有りVer)

**既存パラメータ(例)**
user_name, user_level, flg, matching_state_date_time, etc…

flgの未使用bitを活用。
00[1]11111

**パラメータを追加せず、データ転送量も同量で済んだ！**

---

# 権限(認可)管理フラグ(bit演算無しVer)

要件
* 管理ツールでアカウント毎に権限を持たせたい

DBにinteger型のauthorityカラムを用意
(例)
1:閲覧、10:編集、100:設定変更、1000:管理者

**編集権限があるか判定したい場合**
該当の桁数の数字を抽出したりするような処理になりそう。
**判定処理に手間が掛かる。**

---

# 権限(認可)管理フラグ(bit演算有りVer)

DBにbit型のauthorityカラムを用意
(例)
0001:閲覧、0010:編集、0100:設定変更、1000:管理者

**編集権限があるか判定したい場合**

```
return user.authority & AUTHORITY_EDIT
```

**bit演算ANDを活用すれば処理もスッキリ！**

---

# まとめ

* 複数フラグを管理するのに絶大な効果を発揮する
* 1バイトで管理出来るので容量もコンパクト
* 判定処理も配列使わずともそのまま処理できるので便利

最後まで読んで頂きありがとうございましたm(_ _)m

※bit演算無しVerは有りVerを引き立たせるために極端な例にしています。
for文と拡張For文の備忘録

### はじめに
エンジニア歴1年目。
業務でJavaを触り始めて3か月程度の駆け出しエンジニア。
Javaには苦手意識があるが、技術力、実践力を身に着けたい。
学んだことや調べたことなどの備忘録。

### javaのfor文とは
繰り返し処理の中でも、繰り返す回数が決まっている場合に用いる構文。
```
for(初期化処理; 繰り返し条件; 繰り返し時処理) {
// 条件式がtrueの時に繰り返す処理
}
```
```
for(i = 0; i < 10; i++) {
    System.out.print(i);
}

// 実行結果
0 1 2 3 4 5 6 7 8 9
```

#### 初期化処理
for文の最初に1回だけ実行される。
#### 繰り返し条件
ブロックの内容を実行する前に評価される。
ループを継続するか否かを判定する条件式。
#### 繰り返し時処理
for文内のブロックを最後まで処理し、ブロックの最後まで処理が終了した後に自動的に実行される文。


### javaの拡張for文とは
JDK5から、拡張for文が利用可能。
配列を渡すと、全ての要素をfor文が取り出してくれる。
カウンタ処理が不要。
```
for(要素の型 変数名：配列変数名) {
// 要素を全て取得するまでの処理
}
```
```
int[] ary = {10, 20, 30, 40, 50};
for(int data：ary) {
    System.out.print(data);
}

// 実行結果
10 20 30 40 50
```

拡張for文が、配列から要素を順番に取り出して、宣言された変数に代入される。
全ての要素が取り出されると、for文から抜ける。


### 拡張for文のメリットとデメリット
#### メリット
記述内容がシンプルでコーディングもしやすく、可読性も優れている。
#### デメリット
要素の指定ができない。

### 結論
拡張for文が使えるときは使っていくか検討して、使えないときはfor文とするのがよさそう。

### 最後に
Javaに関する知識をメインに更新予定。
Java初学者から一人前のエンジニアになるための、基礎から実践的な内容など様々な記事を投稿したい。
WWWを支える技術「HTTPS」

# WWWを支える技術「HTTPS」
## 初めに
インターネットと聞いて多くの人が頭の中に思い浮かべるのはWorld Wide Web(WWW)ではないだろうか？
 
 私が中学生の頃は、インターネットというのはgoogleやInternet Explorerなどのwebブラウザだとばかり思い込んでいた。
 

 
 それから、大学生になり、授業で習うまではインターネットというのがWWWを含めるもっと広義なものであると知らなかった。
 
 
 それほど、WWWは現在世界中の人々の私生活に浸透し、欠かせないものになっており、インターネットの中でも代表格の技術であると思う。
 
 
 そこで今回はWWWを支える技術の一つであるHTTPSの概要をまとめてみる
 
## HTTPSの概要
　HTTPSとは「HTTP over SSL/TLS」の略で、
 HTTPに **暗号化技術** を適用したものである。
 
 まず、HTTPとは「Hyper Text Transfer Protocol」の略で、 1980~1990年代にかけてティム・バーナース＝リーと ロバート・カイリューによって開発された技術である。
 
 
 HTMLやXMLにより記述されたハイパーテキストを使い、 ネットワーク上で通信する仕組みで、 画像や音声といったデータを取り扱うことも可能である。
 
 
 
 これらのデータをサーバとクライアントとの間で通信する時の**通信規約(プロトコル)が、HTTP**である。

 しかし、HTTPで通信を行うと、第三者に通信の内容を盗み見られてしまうという問題点がある。
 
 そこで第三者に情報を盗み見られることを防ぐために **HTTPS**が開発されることになった。

 
 一方、SSLは「Secure Socket Layer」、
 TLSは「Transport Layer Security」の略で、
 それぞれネットワーク上で暗号化通信する仕組み（プロトコル）である。
 
 
 現在はTLSで暗号化を行っており、 SSL自体は使われてはいないが、
 常時SSLと言うのが一般的である[1]。
 
　通常のHTTPを使った通信では、webサーバ側のTCPのポート番号は80番となっている。
 
 一方HTTPSの場合は433番でSSL/TLSのポートを待ち受けしている。
 
 
 Webブラウザがこのポート番号に接続することで、最初にSSL/TLSの通信路の開設処理を行う。
 
 SSL/TLSはステートを持つプロトコルであり、暗号アルゴリズムの選択や証明書情報の交換、暗号化用の鍵データの交換などのやり取りを行って暗号化通信路を開設する。
 
以上の通信路開設処理を完了すれば、あとはその上でHTTPプロトコルによる通信を行う[2]。

つまり**HTTPSとHTTPの違いはこの暗号化通信の開設をするかしないか**である。

そして、通信がHTTPで行われているのか、HTTPSで行われているのかを知るには、webブラウザのアドレスバーを見る。http:/であればHTTP、https:/に合わせて鍵のマークが表記されていればHTTPSで通信していることになる。

また、HTTPSで通信をする目的としては、個人情報や機密情報といった第三者に傍受されたくない情報を含んだ通信を安全に行いたい場合に必要とされる。

特にECサイトやインターネットバンキングなどの個人情報を入力するサイトやページに適用され、通信中での第三者によるなりすましなどを防止する[1]。

以前は、ログイン画面等の個人情報を入力するページのみがHTTPS、その他はHTTP、というwebページ構成も多くあった。そして、最近ではコーポレートサイトや、サービスサイトなどの個人情報を取り扱わないサイトでも使用されるようになってきている。


　次にHTTPSで暗号化通信路を開設する際にwebサーバからクライアントに送信されるSSLサーバ証明書について説明する。
 
 webサーバがhttpsに対応するためには、信頼性が高いと認められた認証局(CA : Certification Authority)から発行されたSSLサーバ証明書というものを取得しなければならない。
 
 SSLサーバ証明書は暗号化のカギとして利用されるだけでなく、そのwebサーバがある特定のドメインに属している正当なシステムであることを保証したり、ユーザに対して、そのドメインが正規の組織が管理しているドメインであることを表明する重要な役割を持つ。
 
 SSLサーバ証明書にはwebサーバの所有者の情報や暗号化に必要な鍵などが含まれ、それが発行者によって電子署名されている。以下にwebサーバにセットする証明書の種類を表にして示す。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3690136/a523867d-29bd-7341-b20e-938cf93ac66c.png)
 参考: https://www.atmarkit.co.jp/ait/articles/1704/13/news030_2.html

DVからOV、EVとなるにつれて所有者の存在確認などが厳しくなり、その分証明書としての信頼性が高くなるが、コストも上昇する。

また、Let’s Encryptのような無料の証明書サービスもあり、以前よりHTTPS導入のためのハードルは低くなってきている。以上がHTTPSの概要である。


## 参考文献

[1]https://www.shadan-kun.com/blog/measure/374/
[2]https://www.atmarkit.co.jp/ait/articles/1704/13/news030.html
AWS EC2でNext.jsの環境構築する際の備忘録

# 概要
Next.jsをEC2を利用してデプロイする際の環境構築をする機会がありましたので、その際に出会った問題を羅列しております。

## 環境
- Ansible
- Capistrano
- Ubuntu v22.04.3
- Next.js v14.x

## Node.jsのインストール
Ubuntu標準のNode.jsパッケージはv10.xのため、NodeSourceを利用して指定のバージョンをインストールします。

```ansible/task.yml
# nodeの特定のバージョンをインストールするための下準備
- name: import gpg key
  apt_key:
    url: https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key
    keyring: /etc/apt/keyrings/nodesource.gpg

- name: create nodesource repository
  apt_repository:
    repo: deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main
    filename: nodesource.list
    state: present

- name: Install nodejs
  apt:
    name: nodejs
    update-cache: true
  become: true
```

参考:
Ubuntu 22.04 LTSへの最新版Node.jsのインストール
https://self-development.info/ubuntu-22-04-lts%E3%81%B8%E3%81%AE%E6%9C%80%E6%96%B0%E7%89%88node-js%E3%81%AE%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/

## PM2のインストール
Next.jsのサーバーはデーモン化が出来ないため、Capistranoのサーバー起動処理がリターンしません。
そのためNodeのスクリプトをデーモン化できるPM2を利用します。
また、PM2のログローテーションの設定にはpm2-logrotateを利用します。
PM2は`pm2 install`を行えるPlaybookが存在しないので、苦肉の策として`shell`を利用しています。

PM2のモジュールをインストールする場合、実行ユーザーに注意が必要です。
`become: true`のみ指定した場合、rootのみにモジュールがインストールされてしまいます。
`become_user: xxxxx`で正しいユーザーを指定しましょう。

```ansible/task.yml
- name: Install pm2
  community.general.npm:
    name: pm2
    global: true

- name: Install pm2 logrotate
  shell: "pm2 install pm2-logrotate"
  become: false

- name: set pm2 logrotate config TZ
  shell: "pm2 set pm2-logrotate:TZ Asia/Tokyo"
  become: false

# ログをデイリーの0時0分に切り替え
- name: set pm2 logrotate config interval
  shell: "pm2 set pm2-logrotate:rotateInterval '*/0 0 * * *'"
  become: false

- name: set pm2 logrotate config max_size
  shell: "pm2 set pm2-logrotate:max_size 100M"
  become: false
```

参考
[node.js][pm2][ts-node]PM2を使ってアプリケーションを永続化・ログローテーションでログを管理する
https://zenn.dev/tsonwk/articles/3f76ce1ff60a78

※pm2-logrotateの設定をecosystemファイルに記載することは出来ない(↓公式issue)
https://github.com/keymetrics/pm2-logrotate/issues/131

## ビルドIDの固定
Next.jsアプリはビルドした際に固有のビルドIDを持ち、ビルドIDが異なる場合はエラーが発生します。そのため、複数のインスタンスでビルドを行う場合、ビルドIDを固定にする設定が必要です。
Capistranoの場合、リリースしたディレクトリに最新のコミットが記載されている`REVISION`ファイルが生成されるので、それを利用します。

```package.json
  "scripts": {
    "build": "GIT_COMMIT_HASH=$(cat REVISION) next build",
  }
```

```next.config.js
const buildId = process.env.GIT_COMMIT_HASH

const nextConfig = {
  // ビルドIDの統一
  generateBuildId: async () => {
    // ハッシュはcapistranoにより生成されるREVISIONファイルから取得
    console.log(`BUILD_ID: ${buildId}`)
    return buildId
  },
}
```
参考
公式DOC：ビルドIDの設定
https://nextjs-ja-translation-docs.vercel.app/docs/api-reference/next.config.js/configuring-the-build-id

AWS EC2でNext.jsの環境構築
https://blog.vivita.io/entry/2020/08/17/112932

## あとがき
コンテナであれば起きない問題がいくつか発生し、ハマることが多かったです。(現在もcssのファイル名がビルド毎に異なる問題にハマっています)
この記事がどなたかの助けになれば幸いです。
神経衰弱でカードを並べる

神経衰弱でカードをランダムに並べて表示できるようにします。前回の記事のカードをめくる処理の続きから始めます。

# 前回の記事
https://qiita.com/yanagiiiiiii_t/items/a9ff9f1665b7a75be9ac

# カードを並べる
カードの画像は前回の記事の引用元からダウンロードします。カードはc01～c13、d01～d13、h01～h13、s01～s13の合計52種類あり、手動で配置すると大変なのでスクリプトで配置します。
まずは52枚の画像をHierarchyビューにドラッグし、さらにHierarchyからProjectビューにドラッグすることでプレハブ化します。またカードの裏面となるz01も同じようにプレハブ化しておきます。
以下のスクリプトを作成してMain Cameraにアタッチします。

```C#:CardManager.cs
using System.Linq;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CardManager : MonoBehaviour
{
    public GameObject[] cards = new GameObject[52]; //カードの表52種類を格納する配列
    public GameObject cardBack; //カードの裏を格納する変数

    void Start()
    {
        System.Random random = new System.Random();
        cards = cards.OrderBy(x => random.Next()).ToArray(); //配列をシャッフルする

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 13; j++)
            {
                GameObject cardPrefab = Instantiate(cards[i * 13 + j], new Vector2(j * 3, i * 4), Quaternion.identity); //カードの表の画像を4x13の形に等間隔で並べる
                GameObject backPrefab = Instantiate(cardBack, cardPrefab.transform); //カードの裏面を表面の子オブジェクトとして生成する
                cardPrefab.AddComponent<BoxCollider>(); //カードの表にはBoxColliderをアタッチする
                backPrefab.transform.localPosition = Vector2.zero; //カードの裏のローカル座標を(0, 0)に設定する
                backPrefab.GetComponent<SpriteRenderer>().sortingOrder = 1; //カードの裏のOrder in Layerを1に設定する
            }
        }
    }
}
```

Main CameraにアタッチしたらInspectorビューで、cardsのElement0～Element51にc01～c13、d01～d13、h01～h13、s01～s13のプレハブをドラッグします。またCard Backにはz01のプレハブをドラッグします。
これで実行すれば52枚のカードが縦4枚、横13枚の長方形の形に等間隔で並びます。
後は52枚のカードが画面にすべて収まるようにMain Cameraの位置を調整します。参考までに、InspectorビューでMain CameraのPositionをX=17.5、Y=6、Z=-10、Sizeを9にすると下の図のように綺麗に収まります。

![Image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3644510/a86c67a2-cd7e-5bd2-04d6-747dfc32af40.png)

カードをクリックするとカードがめくれるのでランダムに配置されていることがわかります。

# 参考
https://www.choge-blog.com/programming/csharplistfhuffle/
React18のsuspenseとtransitionの組み合わせ

```App.tsx
import React, {Suspense, useState, useTransition} from 'react';
import {ErrorBoundary} from "react-error-boundary";
import AlbumList from "./AlbumList.tsx";
import Sidebar from "./Sidebar.tsx";
import TodoList from "./TodoList.tsx";

type Tabs = "todo" | "album";

const ReactQuery = () => {
  const [selectedTab, setSelectedTab] = useState<Tabs>("todo");
  const [isPending, startTransition] = useTransition();

  const buttonStyle = {
    padding: "12px",
    fontSize: "16px",
    border: "none",
    opacity: isPending ? 0.5 : 1
  }
  const albumButtonStyle = {
    ...buttonStyle,
    background: selectedTab === "album" ? "royalblue" : "white",
    color: selectedTab === "album" ? "white" : "black"
  }
  const todoButtonStyle = {
    ...buttonStyle,
    background: selectedTab === "todo" ? "royalblue" : "white",
    color: selectedTab === "todo" ? "white" : "black"
  }

  const onClickTabButton = (tab:Tabs) => {
    startTransition(() => {
      setSelectedTab(tab);
    })
  }

  return (
    <>
      <p>ReactQuery</p>

      <div style={{display: "flex", padding: "16px"}}>
        <Sidebar />

        <div style={{flexGrow: 1}}>
          <button style={todoButtonStyle} onClick={() => onClickTabButton("todo")}>todo</button>
          <button style={albumButtonStyle} onClick={() => onClickTabButton("album")}>Album</button>

          <ErrorBoundary fallback={<p>todo or album リストエラーです</p>}>
            <Suspense fallback={<p>todo or albumリストローディング中</p>}>
              {selectedTab === "todo" ? <TodoList /> : <AlbumList />}
            </Suspense>
          </ErrorBoundary>
        </div>
      </div>
    </>
  );
};

export default ReactQuery;

```
databricksを使ってみた

[第2回 金融データ活用チャレンジ ](https://signate.jp/competitions/1325)で提供された開発環境databricksにお世話になったお礼を兼ねて使ってみた感想を列挙する

# よかった点

1. AutoMLで高性能モデルを構築
   ノーコードで滅茶苦茶簡単
   [databricksのAutoMLでモデルの最適ハイパーパラメータを探索](https://qiita.com/t-tsue/items/a14e14bfcebbbd16f970)

2. notebookのバージョン管理
   submitが60回を超えるとsubmission.csvとモデルや学習データの対応が怪しくなるがdatabricksのバージョン管理機能はそんな悩みを払拭してくれる
   [databricksのバージョン管理](https://qiita.com/t-tsue/items/a0018a20ac8b6c24a770)

3. 時間制限
   無償版のGoogle Colabではブラウザを閉じて90分経過するとランタイムがシャットダウンする(2024/2/13時点)がdatabricksにはそのような時間制限はない
   寝る時間に “ぽちっとな” とモデルの学習を開始してPCをシャットダウン
   翌日PCを起動してブラウザを立ち上げnotebookに接続すると学習済みモデルができあがっている
    [databricksの時間制限](https://qiita.com/t-tsue/items/eb1dc88a50312be01a61)

4. AIがコード生成
   [APIリファレンス](https://scikit-learn.org/stable/modules/classes.html)を検索することなくコーディングが可能
    [databricksのAIコード生成](https://qiita.com/t-tsue/items/fdd1906b89eb58942499)

# 個人的要望 or 反省
1. GPUクラスタがほしかった
   CatBoostやSVM系のライブラリは処理時間がかかるのでGPUクラスタがあればありがたい

2. GitHub連携を試す時間がなかった
   databricksのバージョン履歴とGitHubのコミット&プッシュを理解して上手に活用すればよりスマートなソース管理が実現できたと思うが時間的制約からcloneを連発し無駄なnotebookがたくさんできてしまった

 ![GitHub](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3687201/214c9a3f-8684-d3dc-a72d-602ab70bf1c4.png)
Railsでデータを効率的にカウントする方法

### 自己紹介
現在、SEとして業務系システムの開発に従事している者です。
WEBエンジニアとして転身するにあたり、主にRuby on RailsとNext.jsを中心とした勉強をしています。
よろしくお願いします。

---------------

今日は、Railsでデータをカウントする際に便利な`count`関数の使い方について詳しく解説します。データの数を数えることは、Webアプリケーション開発においてよくある要件の一つです。Railsでは、このようなデータ操作を簡単かつ効率的に行うためのメソッドが豊富に用意されています。

### `count`メソッドの基本

`count`メソッドは、ActiveRecordのスコープに対して呼び出すことができ、指定された条件にマッチするレコードの数を返します。最もシンプルな形では、モデル全体のレコード数を取得することができます。

```ruby

User.count

```

このコードは、`users`テーブルのレコード総数を返します。

### 条件付きカウント

`count`メソッドは、条件を指定して特定のレコードの数をカウントすることもできます。例えば、特定の条件を満たすユーザーの数を知りたい場合、`where`メソッドと組み合わせることができます。

```ruby

User.where(active: true).count

```

この例では、`active`カラムが`true`であるユーザーの数をカウントしています。

### グループ化されたカウント

複数のレコードを条件に応じてグループ分けし、それぞれのグループに含まれるレコードの数をカウントすることも可能です。これは`group`メソッドを使用して行います。

```ruby

User.group(:country).count

```

このコードは、ユーザーを国別にグループ化し、各国に登録されているユーザーの数を返します。

### パフォーマンスの考慮

`count`メソッドを使用する際は、パフォーマンスにも注意が必要です。大量のデータが存在する場合、データベースに大きな負荷がかかることがあります。効率的なクエリを心がけ、必要な場合は`counter_cache`オプションを利用して、レコードの数をキャッシュすることを検討しましょう。

### まとめ

`count`メソッドは、Rails開発において非常に便利なツールです。この記事を通じて、その基本的な使い方から、より高度な利用方法までを理解し、あなたのRailsアプリケーションに活用してみてください。効率的なデータ操作をマスターすることで、より応答性の高いアプリケーションを開発することができます。

これからも、Railsの様々な機能を使いこなし、素晴らしいWebアプリケーションを作っていきましょう。Happy coding!
Co-Locationについて理解する

# 背景

https://www.youtube.com/playlist?list=PLwM1-TnN_NN6fUhOoZyU4iZiwhLyISopO

こちらのReact講座でCo-Locationというものを知った為です。

# Co-Locationとは

https://legacy.reactjs.org/docs/faq-structure.html

ファイル構成の考え方の一つで、```よく一緒に変更されるファイルを近くに置いておく```ことだそうです。

# 最後に
- 普段自分がしていたファイル構成の手法の問題点も分かりました
- Co-Locationの考えと様々なファイル構成の手法を掛け合わせてその都度最適な選択をしたいです
【SQL】STRING_SPLIT で分割した値を変数に代入する

## はじめに

SQL Server 2016 以降で使用できる **STRING_SPLIT** は便利な関数ですが、分割した値を変数に代入するサンプルを、なかなかネットで見つけられず随分と悩んだので、そのコードを共有します。

:::note info
STRING_SPLIT の詳細はこちら
[STRING_SPLIT (Transact-SQL) - SQL Server | Microsoft Learn](https://learn.microsoft.com/ja-jp/sql/t-sql/functions/string-split-transact-sql)
:::

## 前提

前提として、STRING_SPLIT の第3の引数 enable_ordinal を有効(1)にすると、分割された部分文字列が並ぶ value 列とともに、ordinal 列（序数）が返ります。
```SQL
SELECT * FROM STRING_SPLIT('All about SQL,2013/5/20,3800', ',', 1);
```
結果
| value           | ordinal|
|:----------------|-------:|
| All about SQL   | 1      |
| 2013/5/20       | 2      |
| 3800            | 3      |

この ordinal 列を利用します。

## 表題のサンプルコード

```SQL:T-SQL
DECLARE @title   varchar(30)
DECLARE @pubdate date
DECLARE @price   int
DECLARE @buf varchar(50) = 'All about SQL,2013/5/20,3800'

SELECT @title   = CAST(value as varchar(30)) FROM STRING_SPLIT(@buf, ',', 1) WHERE ordinal=1;
SELECT @pubdate = CAST(value as date)        FROM STRING_SPLIT(@buf, ',', 1) WHERE ordinal=2;
SELECT @price   = CAST(value as int )        FROM STRING_SPLIT(@buf, ',', 1) WHERE ordinal=3;
```

これで各々の変数に、分割された値が型変換されて入ります。
しかし、コードが冗長なので、 SELECT 一本にまとめます。（ DECLARE 部は省略）

```SQL:T-SQL
SELECT
	@title   = CASE ordinal WHEN 1 THEN CAST(value as varchar(20)) ELSE @title   END
,	@pubdate = CASE ordinal WHEN 2 THEN CAST(value as date)        ELSE @pubdate END
,	@price   = CASE ordinal WHEN 3 THEN CAST(value as int)         ELSE @price   END
FROM STRING_SPLIT(@buf, ',', 1);

SELECT @title as [題名], @pubdate as [発売日], @price as [価格];
```

結果
| 題名          | 発売日      | 価格 |
|:--------------|------------|-----:|
| All about SQL | 2013-05-20 | 3800 |

実際のコードでは、 value を TRIM で囲って余分な空白があれば除去するとか、
CAST ではなく TRY_CAST を使って安全に型変換するとかが必要になると思います。

## 最後に注意点

なお、最後になりましたが、先の Microsoft の STRING_SPLIT 説明ページに、気になる一文があります。

> [出力行には任意の順序を指定できます。この順序が入力文字列の部分文字列の順序と一致するかどうかは保証されません。](https://learn.microsoft.com/ja-jp/sql/t-sql/functions/string-split-transact-sql#remarks)

これが、分割された部分文字列の順序と ordinal 列の序数の値が必ずしも一致しない（左端から 1, 2, 3, ... とならない場合もある）ことを指すのか、それとも、 SELECT から返される結果の順序が順不同であることを指すのか、私にははっきりと読み取れません。（どうも前者っぽい気はしますが。）

ただ、私がこのサンプルコードをテストしたり、この例のように 1 行の入力文字列を 3 分割して変数に代入する処理を 300 行程度繰り返した限りにおいては、うまく動作しました。

ということで、この注意点を踏まえた上で、このコードを参考にしていただけますと幸いです。
TeXで数式などを画像にする方法

powerpointなどで数式を書きたい場合，数式エディタを使うのもよいが，TeXに慣れている人だと面倒であろう．webで数式を画像出力するサービスもあるが，ubuntuなどのLinux環境であれば，pdfを画像に変換すればローカルで画像を作ることができる．

# 準備

好きなtexソースファイルで，数式を出力する．自分の好きなプリアンブルでよいが，たとえば，次のようなソースファイルを準備する．

``` tex2png.tex
\documentclass[leqno,uplatex,dvipdfmx]{amsart} 
% フォントのサイズ指定の都合で，jsarticleは避けた方がよい
%
\usepackage{amssymb} % AMSの記号強化パッケージ
\usepackage{mathrsfs} % 花文字を出力できるようにする
\usepackage{otf} % 和文 OpenType フォントを使えるようにする
\usepackage{graphicx,color}

%%%%%%%%%%%%%%% フォントの設定
 
\usepackage{newtxtext} % TXフォントを使う
\usepackage[varg]{newtxmath} % TXフォントを使う
\usepackage{pxchfon}[ipaex] % 日本語はipaexフォントを使う

%%%%%%%%%%%%%%% Paper size settings %%%%%%%%%%%%%%%
%
\usepackage{geometry}
\geometry{a4paper}
\geometry{landscape}
\geometry{top=1cm, bottom=1cm, left=1cm, right=1cm}
%

\begin{document}

\thispagestyle{empty}
\fontsize{24pt}{24pt}\selectfont

\end{document}
``` 

# コマンド

TeXソースファイルからpdfを作り，pdfcropを使って不要な空白を削除し，pdftoppmで画像に変換する．TeXのコンパイルは各自の好きなやり方をすればよい．makeを使えるなら，これらをまとめて，makefileに書いておけばよいだろう．

```
ptex2pdf -u -l tex2png.tex 
pdfcrop tex2png.pdf tmp.pdf
pdftoppm -png -r 300 -singlefile tmp.pdf tex2png
```

pdftoppmの-pngはpngファイルを出力するオプション，-r 300は解像度を300DPIとするオプション， -singlefileは画像を1つのファイルに出力するオプションである．
【GLSL】bit演算お絵描き

# 概要
GLSLのuintは、bit列を2進数表示した数値で表されます。これを利用して、16進数で指定した値でお絵描きをします。

なお、GLSLのビット演算は`ES 3.0`以降で利用できます。

https://nemutas.github.io/webgl-sketch/20240208/
![63f16fd4-1454-451e-836c-a9b06fcbe3a6.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/af3eccff-ba8d-4882-7ffe-2da69d3071db.gif)

# 進数計算
10進数，16進数，2進数は、それぞれ下表で対応付けされます。
![スクリーンショット 2024-02-13 204959.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/0c42897d-7f6c-e2e6-2bfa-79a8856825d6.png)
一般に、n進数を10進数に直す場合、数をnのべき乗の和に直すことによって表現されます。
例えば、2進数から10進数の場合、
```math
1101_2 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13
```
となり、16進数では対応表により、`D`となります。

# 👾
space invader👾を描画する場合。

![スクリーンショット 2024-02-13 205719.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/ded25a36-48f2-ea84-7897-6de31cfd7de9.png)

例えば、下列の4bitでは、
■☐☐☐
であるので、
```math
1000_2 = 1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 0 * 2^0 = 8 + 0 + 0 + 0 = 8_{10} = 8_{16}
```
となります。
次の4bitは、
■■☐■
なので、
```math
1101_2 = 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 = 8 + 4 + 0 + 1 = 13_{10} = D_{16}
```
となります。
この調子で計算すると、下列は16進数で、
```glsl
0x0d8u
```
となり、全体のbitmapは次のようになります。
```glsl
uint[8] rows = uint[](
    0x0d8u,
    0x505u,
    0x5fdu,
    0x7ffu,
    0x376u,
    0x1fcu,
    0x088u,
    0x104u
);
```

# 表示

```glsl
vec2 iuv = floor(uv * 32.0);

uint[8] rows = uint[](
    ...
);

if (int(iuv.y) < rows.length()) {
    uint b = rows[int(iuv.y)];
    b = (b << uint(iuv.x)) >> 31;
    float c = float(b);
}
```

uintは32bitの2進数bit列なので、uvを32倍して`floor()`をとることで、0~31の整数に変換します。
`iuv.y`で対象のbit列`b`を取得して、`iuv.x`分を左シフトします。
その後に、31bit分右シフトすると対象のセルに対するbit値を取得できます。

例えば、`0x0d8u`の場合、bit列は、
```glsl
0000 0000 0000 0000 0000 0000 1101 1000
```
なので、8bit目の`1`を取得する場合、
```glsl
b = 0000 0000 0000 0000 0000 0000 1101 1000
b << 23 // 31 - 8
b = 1101 1000 0000 0000 0000 0000 0000 0000
b >> 31
b = 0000 0000 0000 0000 0000 0000 0000 0001
```
となります。

bitシフトは、左シフトした場合は、あふれた分が下位bitに表示されます。
```glsl
b = 1000 0000 0000 0000 0000 0000 0000 0001
b << 1
b = 0000 0000 0000 0000 0000 0000 0000 0011
```

右シフトした場合は、あふれた分が削除され上位bitは`0`で埋められます。
```glsl
b = 1000 0000 0000 0000 0000 0000 0000 0001
b >> 1
b = 0100 0000 0000 0000 0000 0000 0000 0000
```

# 作品
画面右下の`source`からコードを参照できます。

https://nemutas.github.io/webgl-sketch/20240205/

https://nemutas.github.io/webgl-sketch/20240207/

https://nemutas.github.io/webgl-sketch/20240207_2/

https://nemutas.github.io/webgl-sketch/20240208/

作品はすべてローカル環境で作成していますが、`twigl`でも再現できます。（おそらく）
https://twigl.app/

twiglを使用する場合は、Regulationを`classic(300es)`にします。
![スクリーンショット 2024-02-13 222236.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/358498/869ac36a-de2d-657b-1a71-f33a16330089.png)


# Reference
[リアルタイムグラフィックスの数学 ― GLSLではじめるシェーダプログラミング](https://amzn.asia/d/9lg7Xv4)
【ChatGPT】Twitterの炎上チェック

ツイート内容が炎上しないか、ChatGPTでチェックする

# プロンプト
```
#指示
あなたは法務担当者です。
以下の#投稿文が炎上しないか、チェックしてください。

#投稿文
（ここに投稿文）

#出力
以下を出力してください。
・炎上可否
・理由
・修正内容
```

# 利用例

## 入力したプロンプト
```
#指示
あなたは法務担当者です。
以下の#投稿文が炎上しないか、チェックしてください。

#投稿文
サンプルベーカリーで買った食パンがとても美味しかった！
ゴワゴワした食感が好み！

#出力
以下を出力してください。
・炎上可否
・理由
・修正内容
```

## レスポンス（GPT-3.5）
```
# 出力
・炎上可否: 可能性が低い
・理由: 投稿文自体はポジティブであり、商品の評価に関する個人的な意見を述べているため、大きな論争の引き金となる要素は見当たりません。
・修正内容: 特に修正する必要はありません。ただし、万が一の場合に備えて、公式な口コミやレビューを行う際には、より客観的な言葉を使用することが望ましいです。
```

## レスポンス（GPT-4）
```
## 炎上可否
炎上する可能性は低いです。

## 理由
この投稿文は、サンプルベーカリーの食パンに対する個人的な好みと肯定的な体験を共有しています。ポジティブな意見や個人の好みを表明しているため、一般的には炎上するリスクは低いと考えられます。ただし、「ゴワゴワした食感が好み！」という表現は、一部の読者によっては食パンの品質が悪いと誤解される可能性があります。しかし、この文脈では明らかに好意的な意味合いで使用されており、個人の好みを強調しているため、大きな問題にはならないと思われます。

## 修正内容
もしもさらに誤解の余地を減らし、ポジティブなメッセージを強化したい場合は、表現を若干変更することが考えられます。

修正前：「ゴワゴワした食感が好み！」
修正後：「しっかりとした食感が私の好みにぴったりでした！」

このように表現を調整することで、「ゴワゴワ」という言葉が持つネガティブなニュアンスを避け、より一般的に好意的に受け取られる表現に変えることができます。これにより、食パンの特徴をポジティブな体験としてより明確に伝えることが可能になります。
```
Rails7のログアウトエラー

`app/javascript/application.js`

```javascript
import $ from "jquery";
```

`application.html.erb`

```erb
<%#= javascript_include_tag 'application', 'data-turbo-track': 'reload', defer: true, type: 'module' %>
```

注意: この設定を行うと、ログアウト時に `ActiveRecord::RecordNotFound at /customers/sign_out Couldn't find Customer with 'id'=sign_out` のエラーが発生します。

## 参考文献
https://qiita.com/jnchito/items/5c41a7031404c313da1f
Django Allauth実装後にaccounts/~にアクセスするとルーティングエラーが発生する

~~~Python
User
django.urls.exceptions.NoReverseMatch: Reverse for 'diary_list ' not found. 'diary_list ' is not a valid view function or pattern name.
2024-02-13 21:46:14,322	[ERROR]	C:\Users\genki\venv_private_diary\Lib\site-packages\django\core\servers\basehttp.py(Line:212)	"GET /accounts/signup/ HTTP/1.1" 500 134792
~~~

そもそもこれはルーティングが間違っている可能性大
diary_listは認証が完了しているユーザーにしか表示されないため、accounts/~にアクセスしたときは認証前であることからdiary_listがあるページに飛ぶのがおかしい

調べた結果settings.pyの記述順がいけなかった

~~~Python:settings.py
# 間違った記述方法

AUTHENTICATION_BACKENDS = (
    'allauth.account.auth_backends.AuthenticationBackend',

    # 一般ユーザー用

    'django.contrib.auth.backends.ModelBackend',

    # 管理サイト用
)

SITE_ID = 1
~~~

~~~Python:settings.py
# 正しい記述方法

SITE_ID = 1

AUTHENTICATION_BACKENDS = (
    'allauth.account.auth_backends.AuthenticationBackend',

    # 一般ユーザー用

    'django.contrib.auth.backends.ModelBackend',

    # 管理サイト用
)
~~~

SITE_IDというのはdjango-allauthで利用するdjango.contrib.sitesを使うためにサイト識別用のIDである
このサイト識別用IDの評価前に認証設定(AUTHENTICATION_BACKENDS)が記載されていたため、ルーティングエラーが発生していた
PythonのSliceの使い方

仕事でよくPythonを使うので、最近改めてPythonを勉強し直しています。
PythonのSliceが便利だったので備忘録としてまとめます。

また、この記事ではリストについて書いていますが、タプルでも同様に扱えます。

# 使い方①　リストから任意の範囲の要素をすべて取得

以下のように書くことで、Sliceを使うことでリストから任意の範囲の要素を取得することができます。

```py
list1 = ["a", "b", "c", "d", "e", "f", "g", "h"]

list2 = list1[2:7]
print(list2) # c d e f gが表示される
```

# 使い方②　リストから任意の範囲の要素を任意の間隔で取得
以下のように書くことで、リストの任意の範囲の要素を任意の間隔で取得することもできます

```py
list1 = ["a", "b", "c", "d", "e", "f", "g", "h"]

list2 = list1[2:7:2]
print(list2) # c e g が表示される
```

# 使い方③　リストから先頭または末尾から任意の数の要素を取得

```py
list1 = ["a", "b", "c", "d", "e", "f", "g", "h"]

list2 = list1[:4]
print(list2) # a b c d が表示される

list3 = list1[5:]
print(list3) # e f g h が表示される

list4 = list1[:4:2]
print(list4) # a c が表示される

list5 = list1[5::2]
print(list5) # e g が表示される
```
上記のように先頭や末尾からデータを取り出す際も、任意の間隔を指定することができます。

# 使い方④　リストを反転する

以下のように書くことでリストの順序を反転することもできます。
```py
list1 = ["a", "b", "c", "d", "e", "f", "g", "h"]

list2 = list1[::-1]
print(list2) # h g f e d c b a が表示される
```


以上となります。

---

【宣伝】
Next.jsを使って技術系ブロクを作りました。
めちゃくちゃのんびり投稿しているので記事は少ないですが、よかったら見てやってください。
こちら
↓
https://www.nattomatofu.com/
【Tips】変数の命名規則について

# 概要
この記事ではプログラムを書く上で気をつけなければいけない「**変数の命名規則**」について触れていきます。
良い命名規則はコードの可読性と保守性を高めるために不可欠なのでぜひ覚えておきたいです(**自戒の念**を込めて)

# キャメルケース
この章では、キャメルケースについて触れていきます。

## 説明
キャメルケースは、各単語の最初の文字を大文字で書きます（例: `camelCaseFlag` or `CamelCaseFlag`）。最初の単語の頭文字を、小文字から始まるのが「 **ローワーキャメルケース** 」、大文字から始めるのが「 **アッパーキャメルケース** 」と言います。個人的にはこの方法をよく使います。TypeScriptをメインで用いる自分はよく使います(チームのコーディングルールにもよる気がするけど)。


## メリット
- **コードの一貫性を保てる。** 
JavaやJavaScriptのような言語では、標準ライブラリや多くのフレームワークがキャメルケースを採用しているため、これに従うことでコード全体の一貫性が保たれます。例えば、JavaScriptのDOM操作関数`getElementById`や`addEventListener`など
　
- **可読性の向上が見込める。** 
識別子が自然言語のフレーズとして読めるため、コードを読む際の理解が早まります。例として `calculateTotalAmount`なら、「総額を計算する」と直感的に理解することができると思います。

## デメリット
- **非英語圏の言語における不自然さを感じること**
非英語圏の開発者が自国語で変数を命名しようとすると、キャメルケースを適用することが難しく、読みにくい名前になる可能性があります。例えば、日本語でお金追加とお金使用(`okaneTuikaToOkaneShiyou`)は不自然に感じでしまうと思います。
　
- **長い識別子の読みづらさを感じる。**
メソッドや変数名が長くなると、キャメルケースでは読みにくさが増します。特に、複数の概念やアクションを一つの識別子に含める必要がある場合、この問題は顕著になります。例: `fetchAndParseUserDataFromDatabase`。

# スネークケース
この章では、スネークケースについて触れていきます。

## 説明
スネークケースは、単語をアンダースコア( `_` )で区切る命名規則です（例: `snake_case_variable` ）。PythonやRubyの変数名や関数名でよく見られるスタイルです。単語がアンダースコアで区切られているため、視覚的に区別しやすくなっている。

## メリット
- **多言語対応の自然さを感じる**
英語以外の言語で変数や関数名を作成する際、スネークケースは自然に見え、読みやすい。例えば、ロシア語やアラビア語のような非ラテン文字系の言語でも、`получить_данные_пользователя`（ユーザーデータを取得する）のように使えるらしいでs。(例が思いつかなくてchatGPTに聞きました。本当にちゃんと翻訳できてるかは怪しいです🇷🇺)
　
- **長い識別子の可読性が高い** 
長い名前もスネークケースにすることで、各単語の区切りが明確になり、読みやすくなります。例として `fetch_and_parse_user_data_from_database`など。

## デメリット
- **言語やフレームワークの制約がある**
JavaScriptのようにスネークケースが一般的でない言語では、統一感のあるコードを書くためにキャメルケースを使う必要があります。このように、スネークケースを採用しているライブラリやフレームワークが少ない言語では、コーディングスタイルが混在する可能性があリます。


# ケバブケース
この章では、ケバブケースについて触れていきます。

## 説明
ケバブケースは、単語をハイフン( `-` )で区切る命名規則です（ 例: `text-white`,`border-b` ）。HTMLやCSSでクラス名を指定する際によく使用されます。視覚的に区切りがはっきりしているため、読みやすさを提供します。例に出したようにBootstrapやTailwindCSSでも採用されてるのでよく使いますね。


## メリット
- **ウェブ開発の一般性**
HTMLやCSSでは、クラス名やIDにケバブケースを使用することが一般的です。例えば、Bootstrapのクラス名 `text-center` や `btn-primary` は、この命名規則に従っています。これにより、ウェブ開発における一貫性が保たれます。

## デメリット
- **プログラミング言語での制限がある**
ほとんどのプログラミング言語では、変数名に( `-` )を含めることができません。これは( `-` )が減算演算子として解釈されるためで、ケバブケースはプログラミングではなく、主にマークアップやスタイルシートに限定されます。

# おわりに

変数の命名規則は、プログラミング言語やプロジェクトの慣習、個人の好みによって異なる場合が往々にしてあると思うので重要なのは、一貫性を持って規則を適用し、コードの可読性と保守性を保つことというのが、なんとなく分かりました。

# 参考文献

https://designsupply-web.com/media/development/4052/

https://qiita.com/shota0616/items/4ac7a8696b3f6ccbe2bc

https://www.wakuwakubank.com/posts/804-it-naming-convention/
【Python】CSVのデータや列名を、指定の値や言葉に一瞬で一括置換する方法

# 概要
CSVファイルの特定の列のデータを置換＆列名を変更して書き出すという処理が必要になったので、Pythonで実装しました。

少しならエクセルとかでパパッと置換作業してしまえば良いですが、たくさんあったり何回も実施する必要があるときは面倒ですよね。ということで以下のPythonコードで、指定のディレクトリにある指定のCSVファイルのデータを置換することができたので紹介します。
 
### BEFORE
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/06a6943d-edf5-5632-a571-70f22d9c6c33.png)

### AFTER
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/c3bb036e-20e3-8d60-263c-c41be8b7e033.png)

# サンプルコード

```py
import pandas as pd
import os


filtered_csv_dir = './'
filtered_csv_filename = 'sample_csv.csv'
filtered_csv_path = os.path.join(filtered_csv_dir, filtered_csv_filename)

# CSVファイルの読み込み
df = pd.read_csv(filtered_csv_path)

# name列のデータを置換
fruit_name_mapping = {
    1: "バナナ",
    2: "りんご",
    3: "レモン",
    4: "もも",
    5: "オレンジ",
    6: "マンゴー"
}
df['name'] = df['name'].map(fruit_name_mapping)

# color列のデータを置換
color_mapping = {
    1: "黄色",
    2: "赤色",
    3: "ピンク色",
    4: "オレンジ色"
}
df['color'] = df['color'].map(color_mapping)

# 列名を変更
df.rename(columns={
    'name': 'フルーツ名',
    'color': '色',
    'quantity': '数量'
}, inplace=True)

# 結果を同じCSVファイルに書き出し
df.to_csv(filtered_csv_path, index=False)
```

## サンプルコード解説
### 1. `read_csv`関数を使用して`DataFrame`として読み込む
まず、データ分析を行うライブラリ`pandas`の`read_csv`関数を使用して、指定したパスのCSVファイルを読み込み、それを`pandas`の`DataFrame`にしています。`DataFrame`とは、`pandas`で扱うデータ構造です。

> Pandas DataFrame とは、表形式のデータを表示、操作する方法の一つです。二次元のデータ構造で、データを行と列に整理してテーブルとして表示します。DataFrame は、ゼロから作成することも、NumPy 配列のような他のデータ構造を利用することも可能です。
> 引用元：[pandas DataFrame - Databricks](https://www.databricks.com/jp/glossary/pandas-dataframe#:~:text=Pandas%20DataFrame%20%E3%81%A8%E3%81%AF%E3%80%81%E8%A1%A8,%E3%81%99%E3%82%8B%E3%81%93%E3%81%A8%E3%82%82%E5%8F%AF%E8%83%BD%E3%81%A7%E3%81%99%E3%80%82)

### 2. `map`関数と辞書を利用してマッピングを作成する
その後、特定の数値をフルーツの名前や色（置換したい言葉）にマッピングするため、辞書を作成。

そして`df['name'].map(fruit_name_mapping)`と`df['color'].map(color_mapping)`を使用して、`'name'`列と`'color'`列の数値をそれぞれ対応するフルーツの名前や色に置換します。ここで使われた`map`関数とは、各要素に対して辞書に基づいて値を変換したりできる関数。辞書のキーが列の元の値と一致し、そのキーに対応する辞書の値が新しい値となります。

つまり、上記の例で言えば、`'name'`列の`1`が`バナナ`に置換される、ということです。

### 3. `rename`メソッドで列名を変更する
列名の変更については、`df.rename`を使用します。これは`DataFrame`の行名や列名を変更するために使用されるメソッドです。ここでも置換したい言葉を辞書型で指定してあげます。

ここの`inplace=True`とは、新しい`DataFrame`を返さずに元の`DataFrame`を直接変更することを意味しています。つまり、CSVファイルの列名を直接置換したい場合は、ここで`True`を指定してあげないといけません。

### 4. `to_csv`メソッドでCSVファイルに書き出す
最後に、`df.to_csv`を使用して、変更を加えた`DataFrame`を同じCSVファイルに書き出します。ちなみに、`index=False`は、`DataFrame`のインデックスをCSVファイルに書き出さないことを指定しています。

`index=True`にして書き出すと以下のようになります。
インデックスが必要な際はこちらを指定すると良いですね。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/6bc43713-ba45-07c9-2ca1-4a429e9d220f.png)
【IT未経験】自宅試験でAZ-900に合格しました。　【合格記】

こんにちは2月9日自宅試験にてAZ-900無事合格しました。僕のスペックを知りたい方は一番最初の記事をご覧ください。

試験対策

勉強開始から合格までの期間は概ね1か月
勉強時間は平日1時間30分～2時間　土日4時間～5時間ぐらい


勉強に関して参考にしたサイトはMicrosoft LearnとUedemyの「合格への近道！Azure Fundamentals AZ-900 試験対策講座」と「最短で合格！Azure Fundamentals AZ-900 試験対策問題集」

まず「合格への近道！Azure Fundamentals AZ-900 試験対策講座」をiPadのノートアプリ（Flexcil）に書き込みながら1週目、「最短で合格！Azure Fundamentals AZ-900 試験対策問題集」の演習テスト1をテストし無事48%しか取れず惨敗

2週目はノートで勉強したのを見ながら行う。分からないことはすぐに調べるの繰り返し
![m-1名称未設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667403/58b87d9b-277f-0f1e-5140-682ff058ff6d.png)
2回目からは80％～最高96％の正解率　演習テスト1~5で90%以上取ることが出来れば試験でも合格範囲に入るかと思います。

たぶんこのぐらいで飽きてくると思うのでMicrosoft LearnのMicrosoft Azure の基礎を勉強し細かい範囲まで理解する。今回の試験では出なかったが、サンドボックスでの操作は行った方がいいかと思う。

自宅試験
試験日を8~9日と考えていたので2月に入る前に試験予約を行いました。
![Screenshot 2024-02-09 at 13-53-42 OnVUE 試験の予約を承りました。システムテストを実行してください。 - nxstlesmo@gmail.com - Gmail.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667403/a8fe1bdb-aef4-04f6-612f-2e766a86e3ba.png)
予約の仕方などは検索すれば出てくるので割愛
幸い日本語の担当者がいる日があったので9日にしました。
メールの下にもありますが、テスト当日までにテスト環境のテストは行った方がよいかと思います。

試験日のトラブル

予約時間30分前にアクセスすると準備が始まり、スマートフォンを使い画像のアップロードなどがありますが
自分の写真を撮るのに画面内が真っくらで端の方に3cm程カメラがとらえている画像が出てる感じで撮影しても映っているかどうか分からない状態。とりあえず適当に撮ってたら映っていたので良し
次に免許の表裏を撮影これは平気だった。
部屋の環境を撮影するのに4方向撮影するが、ここも画面が真っ暗自分を撮影するときは少しだけカメラ内画像が表示されたけど、今回はだめなのでPC側に切り替えて行うことに。
切り替えると免許の画像は送られているようで4方向の撮影だけ行いました。結構難しい

チャットが始まりここでも4方向にカメラを向けて～とかいろいろ指示があって
最後に開始となる。
私の環境では特にあれを退けてとかそういう指示はありませんでした。
![Screenshot 2024-02-13 at 21-33-31 scorereport-1.pdf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3667403/9f017dbb-244d-3531-0d72-f48f398b748c.png)

今回の試験は36問18分で回答し842点でした。
試験中は750点ぐらい？の感触しかありませんでした。試験はUedmyと少し違うので注意Microsoft Learnの知識チェックの出題のような感じ　そういう意味で両方やっておいて損はありません。

IT未経験で受験したので用語に苦労しましたが、「マップ」、「アファリング」、「プロビジョニング」とか
ChatGPTとGoogle Bardを使いやさしく教えて！っていうと分かりやすく教えてくれます。


引き続きDP-900の試験に移りたいと思います。
【Vue.js】基本構文について

## 概要
今回はVue.jsの基本的な構文について学習したいと思います。

## Vueインスタンス
{{ }} でVueインスタンスの要素を呼び出すことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/889833d4-4257-8453-0f2d-13d79c2ffe9d.png)

## v-text
v-textを使えば、指定されたデータプロパティの値が要素のテキストに動的に反映されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/43c57fbc-163c-a193-9cb8-5ab34b1d4e5a.png)


## v-if, v-else
v-if が false の時は、そのHTML要素とその子要素をDOMから取り除きます。
v-else は直前の v-if が false の時に、そのHTML要素とその子要素をDOMに表示させます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/fcc5f80b-3e3f-fb3c-26e7-b87d33269c6b.png)

## v-bind
HTML要素をVue.jsで動的に指定したい場合は、v-bind を使います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/1abad567-32fe-672c-49c7-31d320f2ae4a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/b167a683-f2a6-d2ab-9e02-846413645e95.png)


## v-on
v-onを使えば、DOMイベントが発生した際に、指定したメソッドや式を実行できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/179f9d42-8fd1-115b-608d-5dd840d2dd78.png)

## v-for
v-forを使えば、配列内の各要素に対して繰り返し処理を行い、テンプレート内で動的なリストを生成できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/5df18bdc-983e-c342-299f-3e1eb97042f9.png)

## v-once
v-once をHTMLタグに含めることで1度描画された内容を変更不可にできます。

①![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/c18ad7b8-9192-12aa-36f3-6fb4d1065f7b.png)
②![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/8aed50d3-e31a-59ec-6413-fd67a182adaa.png)

## v-model

v-model を使えば、Vueインスタンスの data をHTML要素にバインドできます。変更された場合は、その値を参照しているDOM全てに反映されます。

①![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/9f434a3b-2750-38b5-be08-d559056a3585.png)
②![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/3d15b34b-39e0-ef41-fa94-b8d469d00f75.png)

## computed
Vueインスタンスの computed オブジェクトは、 methods に似ていますが、data プロパティのように処理結果を保持させる時に使います。methodsと違い、呼び出す時に () は不要です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/25278556-eef4-3141-3683-08139e19ba9a.png)

## ※computed プロパティとmethods メソッドの違い
computed プロパティは、Vue.jsのデータプロパティに基づいて動的なプロパティを生成します。依存するデータが変更されると、computed プロパティも自動的に再評価されます。キャッシュが行われ、同じ依存データが変更されない限り、結果はキャッシュから提供されます。一方でmethods は Vue インスタンス内で呼び出されるメソッドを定義します。これらのメソッドは手動で呼び出す必要があり、キャッシュされず、再評価されません。毎回呼び出されるため、動的な結果を提供できます。

## watch
Vueインスタンスの watch オブジェクトは、特定のプロパティの変化をトリガーに処理を走らせる時に使います。data だけでなく computed のプロパティも watch できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3673845/3151a3e2-81ea-0ffa-972a-0a998fdb386a.png)
自作でフォーム系のコンポーネントを作るときの最小単位

## はじめに
自作でフォーム系のコンポーネント（input, radio, select）を作るときのメモです。

## 環境
`nuxt 3.9.3`
`vue 3.4.13`

## コンポーネント
コンポーネントの実装は以下のようにしています。

```vue
<template>
  <input type="text" @input="updateValue" />
</template>

<script setup lang="ts">
interface Props {
  value: string
}
interface Emits {
  (event: 'update:value', value: string): void
}
const props = defineProps<Props>()
const emit = defineEmits<Emits>()
const value = useVModel(props, 'value', emit)

const updateValue = (event: Event) => {
  value.value = (event.target as HTMLInputElement).value 
}
</script>
```

## 使う側

```vue
<template>
  <div p="12px" flex="~ col" gap="4px" items="start">
    <span>名前</span>
    <AtomsInput v-model:value="name" />
    <span>- {{ name }} -</span>
  </div>
</template>

<script setup lang="ts">
const name = ref<string>('')
</script>
```

## 参考
https://vueuse.org/core/useVModel/
RecyclerViewを使ったリストの逆順表示をしたかった

# きっかけ
RecyclerViewを使ってimageのリストを逆順で表示させようとしたときにうまくいかないポイントがあったので書こうと思いました。

Android開発に携わり始めて一ヶ月である手前、寡聞少見ながら本記事を作成しております。
ご意見やアドバイスなどございましたら是非ともよろしくお願いします。

# やりたかった事
- `データをリスト表示させる時、
並びを逆順で(下から)表示させたい`
- `RecyclerViewにしたときに上部から下方向へむけて表示させたい`
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2646406/a52691bf-19fc-b6fc-ac01-a7b041dedb6f.png" width="200" />

# ためしたこと
**1. GridLayoutManagerを使って並べ替える**


```kotlin:kotlin
//Adapter
//リサイクラービューのリスト、取得方法,数字はあくまで仮定
val exList = listOf(1, 2, 3, 4, 5, 6, 7) 
//~~~

//Fragment
private fun initView() {
        binding.apply {
        val exList = findViewById<RecyclerView>(R.id.ex_list)
        
        val layoutManager = GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, true)
        layoutManager.spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return 1
            }
        }
        exList.layoutManager = layoutManager
        exList.adapter = ExAdapter
    }

 }

```
画像を7枚表示させるとき、`GridLayoutManager`の第四引数で`reverseLayout`をtrueにして逆順での表示を試みてみた

### 結果
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2646406/3ca8fad5-a29b-203e-9394-ddcf0b62f5b6.png" width="200" />

逆順で表示はされたものの下部から上方向への表示となってしまった(この場合スクロールビューも下からの表示となってしまう)。

類似のもので`layoutManager.reverseLayout = true`も試してみたが結果は変わらなかった。そりゃそうか
```kotlin:kotlin
//Adapter
//リサイクラービューのリスト、取得方法,数字はあくまで仮定
val exList = listOf(1, 2, 3, 4, 5, 6, 7) 
//~~~

//Fragment
private fun initView() {
        binding.apply {
        val exList = findViewById<RecyclerView>(R.id.ex_list)
        
        val layoutManager = GridLayoutManager(context, 2, GridLayoutManager.VERTICAL, false)
        layoutManager.reverseLayout = true //ここで逆順にしてみる
        layoutManager.spanSizeLookup = object: GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                return 1
            }
        }
        exList.layoutManager = layoutManager
        exList.adapter = ExAdapter
    }

 }

```

# 最終的にどう対処したか

→Listのdataそのものを「`.reversed()`」で並び替えた
```kotlin:kotlin
val exList = listOf(1, 2, 3, 4, 5, 6, 7).reversed()
```
色々と回りくどく考えてたがこれで「今まで何してたんだよ」ってくらい一発解決した

# わかったこと
- `reverseLayout`でやるとRecyclerViewそのものが反転してしまう
- RecyclerViewの向きをそのままにリストの順を逆にするにはリストデータそのものを`.reversed()`するのが楽
OIを取得してみた（自分用備忘録）

単なる備忘録なので詳細は省きます。

```python openInterest/sample.py
import requests

api_key = 'my api'
symbols = 'BTCUSDT_PERP.A,BTCUSD_PERP.0'
url = 'actual endpoint'

params = {
    'symbols': symbols,
    'api_key': api_key
}

response = requests.get(url, params=params)

if response.status_code == 200:
    data = response.json()
    print("Open Interest Data:", data)
else:
    print(f"Failed to retrieve data. Status code: {response.status_code}, Message: {response.text}")
```

結果
```
Open Interest Data: [{'symbol': 'BTCUSD_PERP.0', 'value': 236370700, 'update': 1707826545124}, {'symbol': 'BTCUSDT_PERP.A', 'value': 92707.774, 'update': 1707826547840}]
```
回帰分析：データから未来を読み解く統計学の基礎

回帰分析とは、データの背後にある関係性を数学的なモデルで表し、予測や理解を深めるための統計的手法です。簡単に言うと、ある事象（目的変数）が、他の一つまたは複数の事象（説明変数）にどのように影響されるかを分析する方法です。

# 単回帰分析
単回帰分析は、統計学における最も基本的な分析手法の一つで、一つの独立変数（説明変数）と一つの従属変数（目的変数）の間の関係をモデル化します。この分析を通じて、変数間の直線的な関係を理解し、予測を行うことが可能になります。

単回帰分析の核心は、二変数間の直線的な関係を表す直線、すなわち回帰直線を見つけることです。この直線は、与えられたデータポイントに最もよく適合するように計算され、変数間の関係を数学的に表現します。

単回帰分析では、回帰直線は \(y = a + bx\) の形で表されます。ここで、\(y\) は目的変数、\(x\) は説明変数、\(a\) は\(y\)軸との交点（切片）、\(b\) は回帰係数（傾き）を表します。回帰係数\(b\)は、説明変数の一単位の変化が目的変数にどれだけ影響を与えるかを示します。

単回帰分析は、ビジネス、経済学、医療、社会科学など、多岐にわたる分野で応用されています。例えば、マーケティングにおいては、広告費用と売上の関係を分析するために使用されます。

# 重回帰分析
重回帰分析は、複数の独立変数（説明変数）と一つの従属変数（目的変数）の間の関係を解析する統計手法です。この分析を通じて、複数の因子が目的変数にどのように影響を与えるかを理解し、より複雑なデータ構造をモデル化することが可能になります。

重回帰分析では、目的変数と複数の説明変数との間の関係を数学的に表現します。

この関係は、\($y = a + b_1x_1 + b_2x_2 + ... + b_nx_n$\) の形で表され、ここで \($y$\) は目的変数、\($x_1, x_2, ..., x_n$\) は説明変数、\($a$\) は切片、\($b_1, b_2, ..., b_n$\) は各説明変数の回帰係数を示します。

重回帰分析を行う際の基本的な手順は以下の通りです：
1. 問題の定義とデータの収集
2. 説明変数と目的変数の選定
3. データの前処理と標準化
4. モデルの構築と回帰係数の推定
5. モデルの評価と適合性の検証
6. 結果の解釈と応用

重回帰分析は、経済予測、金融リスク管理、マーケティング分析、環境科学、医療研究など、多岐にわたる分野で応用されています。例えば、不動産価格の予測においては、立地、広さ、築年数など複数の因子を考慮して価格を推定します。

重回帰分析を行う際には、多重共線性、外れ値、モデルの過剰適合などの問題に注意が必要です。これらの問題を適切に管理し、正確なモデル構築と解釈を行うことが重要です。

# ロジスティック回帰分析
ロジスティック回帰分析は、特定の事象が発生する確率を予測するための統計的手法です。この分析法は、特に二値の結果（例えば、病気の有無や購買行動の有無など）を予測する際に有効であり、医療、マーケティング、ソーシャルメディア分析など、多岐にわたる分野で応用されています。

ロジスティック回帰分析の核心は、ロジスティック関数を用いて、特定の入力（説明変数）から事象の発生確率を推定することにあります。この関数は、オッズ比という概念を通じて、事象の発生確率を0から1の間の値で表現します。分析の過程では、最尤法と呼ばれる手法を用いて、モデルのパラメータを推定します。

実際にロジスティック回帰分析を行う際には、適切なデータセットを選択し、データの前処理を行った後、モデルを構築します。構築されたモデルの性能は、実際のデータに対する予測精度によって評価され、必要に応じてモデルの調整が行われます。


# 回帰分析の流れ
## 1. 説明変数と目的変数を定義する

説明変数（独立変数）と目的変数（従属変数）を定義し、どのような関係性を探求したいのかを決定します。この段階で、分析の目的と方向性が定まります。

## 2. データを収集する

分析に必要なデータを収集します。データは、既存のデータベースから取得することも、新たに調査を行って収集することもあります。このプロセスでは、データの質と量が分析結果の信頼性に直結するため、慎重に行う必要があります。

## 3. モデルを構築する

収集したデータをもとに、数学的なモデルを構築します。このモデルは、説明変数と目的変数の関係性を数式で表現したものです。モデルの構築には、統計ソフトウェアが用いられることが多く、適切なモデル選択が重要になります。

## 4. 分析を実行する

この過程で、モデルの妥当性を検証し、説明変数が目的変数にどのような影響を与えるかを調べます。分析結果は、グラフや表などで視覚的に表示されることが一般的です。

## 5. 結果を解釈する

分析結果をもとに、説明変数と目的変数の関係性を解釈します。この段階では、結果の意味を理解し、それがビジネスなど私たちの実生活においてどのように適用できるかを考えます。