OmniAICreator/Qiita-1.07M huggingface dataset:
AWS Jr.Championsになったこれまでを振り返る

<img width="60%" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179263/b9289003-93ee-3f68-8898-ce90f4a1c128.png">

# はじめに
この記事は私がJr.Championsになってからの８か月間の活動を振り返るものです。

AWS Jr.Champions とは
> AWS Partner Network (APN) 参加企業に所属し、現在社会人歴 1 ～ 3 年目で AWS を積極的に学び、アクションを起こし、周囲に影響を与えている APN 若手エンジニアを選出しコミュニティを形成する、日本独自の表彰プログラムです。

参考：[2023 Japan AWS Jr. Champions の発表
](https://aws.amazon.com/jp/blogs/psa/2023-japan-aws-jr-champions/)


# 自身について
・某SIer企業に所属
・社会人２年目
# 活動の履歴
### 1. DeepRacer部を立ち上げた
自身の会社にはなぜかDeepRacerの実機がありました...が、誰も使っていませんでした。
そこで、社内でコミュニティを立ち上げ、実機検証会を実施しました。
何とかマップ上を走行するところまで持っていけました...
実機だと全然思った通りに動かず、苦労しました。しっかりと動くまで2か月ほどかかりました。


### 2. JAWS-UG にて発表をした
Jr.Championsにならなければ、社外コミュニティで発表するなど考えなかったでしょう...
Jr.Championsの間でこのクライテリアの知名度を向上したい！という動きがあり、それに乗っかった感じです。


発表をする前は自身が作った資料を見て「これで大丈夫か...?」と思っていましたが、
内容より発表をすることが大事、と今なら思います。
そして発表をすると、コミュニティ参加のハードルも下がりますし、何より仲間が増えます。

### 3. AWSの面白さを再認識した
昔からAWSはなんというかユーザフレンドリーでコミュニティとの距離が近い「スタートアップのような」雰囲気を感じていました。
それが個人的に好きでAWSやりたいと就職したわけなのですが...**その感覚が間違っていないことを再認識しました。**
他と比較するわけではないですが、GamedayやRe:Inventに始まるワクワクするイベント、Jr.ChampionsやTop Engineers, Ambassadorsメインのイベント、Jaws UGとの密接な関係性、といったものはAWSが唯一持ち得ているものだと思います。


# Jr.Championsになってよかったこと
### 1.  社外の優秀な方とのつながりが増えた
Jr.Championsは一か月に一度meetupという形で集まりがり、そのうち、オフラインで集まる機会が3-4回程度ありました。
私は北海道という地域にいる分気軽に参加できなかったが、、貯金を削り、生活ができる範囲で参加しました。（東京に行くたび飲みまくっていたことで余計出費が...)

しかし、そのおかげで普通に**会社生活を過ごしているだけでは会えない、同年代（社会人１～３年目）の優秀な方々とつながり**ができたと感じています。


これって結構貴重なことで、ただでさえ社外の同期とは繋がりにくい所、同じ業務（ＡＷＳ）を専門でやっている会社の同期とつながれるのです。
多分**このような機会はこのJr.Championsでしか得られない**と思います。



### 2.  社内でイベント参加の声掛けをもらった

#### ・海外のイベントTechCrunch Disrupt 2023に参加
> [世界最大級のスタートアップイベント「TechCrunch Disrupt 2023」に参加してきた感想](https://qiita.com/bonjiko/items/e57a70352aa9e5c26396)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3179263/8c465a28-762a-b8a7-8016-7d7148d43da0.png)

Jr.Championsということで声掛けをいただき、最新の技術やスタートアップ企業についてみてきました。
「自分が行っていいのだろうか...」という思いもありましたが、「Jr.Championsだし、頑張るか」と、Jr.Championsをモチベーションにして行きました。


#### ・技術コンテストに参加
某大手IT企業が主催する技術コンテストに、弊社代表として参加してきました。
その中でクラウドに関する問題解決を担当してほしい、というところで声掛けがかかり、参加しました。
これもJr.Championsだからこそ声掛けがかかったことだと感じています。

# 今年できなかったこと
### 1. DeepRacer大会で上位５組に入る
　DeepRacerを使った趣味レーション大会がJr.Champions間でありました。大体６０名ほど参加していた大会です。
 なんと**AWSの方から皆に100ドル**をいただき、DeepRacerの学習資金に充て、その枠の中でレースを行いました。
　
 で、結果は30位以下、、ということで、DeepRacerのコミュニティ活動をしている自分にとってとても悔しかったです。

### 2. 個人で開発をする仲間を見つける
　Jaws-UGなどのコミュニティ活動に参加する中で、個人で共同開発をして発表を行っているチームなどがありました。それが羨ましく、自分もしてみたいなぁ...と思って今年が終わってしまいました。
 来年こそは仲間を見つけてやりたい！（コミュ障...)

# 今後していきたいこと
 Jr.Championsも残り３か月ということで、ラストスパートを駆け抜けたいと思います。


### 1. 社内勉強会
　弊社の社内勉強会は３年目に突入しています。AWSに関して、皆が面白いと思ってもらえるような内容を考えていきたいです。
 Jaws UGなどの発表を参考に、輸入するイメージで面白そうな発表をしていく。や運営に入っていく、ということををするのもよいかな思っています。

### 2. 社内コミュニティ活動を主導し続ける
　コミュニティリーダは貴重です。皆業務や私生活でやりたいことがあるからこそ、表立ってやる人はあまりいない...という風に感じています。
　多分自身みたいな「特に深い理由はないけどAWSめっちゃ好き」という人材はかなりレアな気がするので、だからこそ主導してやるべきなのかなぁとも感じています。ただコミュ障なのが難点で、何とかしていきたいです。

 
### 3. 社外勉強会に参加し、発表を定期的に行う
　意外と社外勉強会に参加している人って少ないです。そのうえで発表している人なんて1/10位なのではないかという体感です。
 何もしていないようで周りの知らぬ間に発表していた、というのが究極的にかっこいいと思います。

 ## 終わりに
来年こそはRe:Inventに行きたい。。自費でも良い。。(ハワイ経由）
ViteビルドのHTMLファイルをFlaskで読み込む

# はじめに

FlaskでWebアプリケーションを作成するとき「HTMLファイルはVueやReactなどのフレームワークを使用したいし、TypeScriptで書きたい」と思うことがあります。そうするとViteなどでビルドすることになるのですが、ビルドしたファイルをFlaskで読み込もうとしたら、ちょっと手こずりました。

そんなわけで、ビルドしたHTMLファイルをFlaskで読み込む方法です。

# 結論

`npm run build`でビルドすると出力される`dist`フォルダをpythonのファイルの場所に移動する

```:ディレクトリ構成
├─dist/
│  ├─assets/
│  │  ├─index.js
│  │  └─index.css
│  └─index.html
└─server.py
```

Flaskの静的ファイルの読み込み設定を以下のようにする。

```py:server.py
from flask import Flask, send_from_directory
app = Flask(__name__, static_folder="dist", static_url_path="")

@app.route("/")
def index():
    return send_from_directory(app.static_folder, "index.html")

# MIME type of "text/plain" のエラーが出るなら以下も追加する
import mimetypes
mimetypes.add_type("application/javascript", ".js")

@app.route("/<path:path>")
def send_js(path):
    return send_from_directory(app.static_folder, path)

# 起動
if __name__ == "__main__":
    app.run(debug=True)
```

# なぜ読み込めなかったのか

FlaskはデフォルトのルートディレクトリはFlaskを起動したファイルの場所になります。しかし、ビルドしたHTMLファイルは`index.html`をルートディレクトリとしてjsやcssを読み込もうとします。そのため、設定を何もしないと`index.html`からjsやcssが読み込めません。

```html:index.html
<!-- `index.html` の場所を基準に読み込むようにビルドされている -->
<script type="module" crossorigin src="/assets/index.js"></script>
<link rel="stylesheet" href="/assets/index.css">
```

そこで、以下のように設定を変えます。これで`index.html`のある場所を基準にして、jsやcssなどを読み込むことができます。

```py
# static_folder と static_url_pathの指定で、読み込み設定を変更
app = Flask(__name__, static_folder="dist", static_url_path="")

@app.route("/")
def index():
    # ビルドした静的ファイルを読み込むので 
    # `render_template` ではなく `send_from_directory`を使用する
    return send_from_directory(app.static_folder, "index.html")
```

# まとめ

ViteビルドのHTMLファイルをFlaskで読み込む方法でした。

Vite側とFlask側のそれぞれをサーバ起動する、ということやっている記事は見つけられたのですが、HTMLをビルドして起動をFlaskのみにする方法については、探しても見つけられなかったので記事にしました。


# 参考

https://flask.palletsprojects.com/en/2.3.x/api/
Android 正規表現　カタカナ判定方法

正規表現の文字判定です。
カタカナを判定する方法のサンプルです。

```Validation.kt
fun isKatakana(inputText: String): Boolean {
    val regex = Regex("^[\u30A0-\u30FF　]++\$")
    return inputText.matches(regex)
}
```

個人的に正規表現があまり得意ではなく、すぐ忘れ使う時にまた調べ直したりするので、理解していきたいです。
typescriptでLINE通知するためにやったことメモ

- LINE Developersにアクセスして、LINEビジネスIDを作成
- LINE Developersトップ画面から「新規プロバイダーを作成」ボタンを押下
- トップ > [プロバイダー名]画面から「MessagingAPI」を押下、必須項目を入力して「作成」ボタンを押下
- トップ > [プロバイダー名] > [チャネル名]画面から「Messaging API設定」タブを押下する
    - QRコードをLINEから読み取って、チャネルを自分のLINEアカウントに追加する
    - 画面下部の「チャネルアクセストークン」の「発行」ボタンを押下する
        - トップ > [プロバイダー名] > [チャネル名]画面の「チャネルシークレット」と勘違いした。。。
- トップ > [プロバイダー名] > [チャネル名]画面から、「あなたのユーザーID」を確認する
- ターミナルから以下を実行して、LINE通知が来ることを確認する
    - ```bash
        curl -v -X POST https://api.line.me/v2/bot/message/push \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Bearer {チャネルアクセストークン}' \
        -d '{
            "to": "{あなたのユーザID}",
            "messages":[
                {
                    "type":"text",
                    "text":"hello world1"
                },
                {
                    "type":"text",
                    "text":"hello world2"
                }
            ]
        }'
        ```
- プロジェクト直下で以下を実行して必要なパッケージを追加する
    - ```bash
        npm install @line/bot-sdk
        ```

- 以下を作成する
    - ```typescript:line.ts
        import { messagingApi } from "@line/bot-sdk";
        const { MessagingApiClient } = messagingApi;
        
        const client = new MessagingApiClient({
            channelAccessToken: '{チャネルアクセストークン}',
        });
        
        client.pushMessage({
            to: "{あなたのユーザID}",
            messages: [{type:"text", "text":"hello world1"},{type:"text", "text":"hello world2"},],
        });
        ```

- 以下を実行してLINE通知が来ることを確認する
    - ```bash
        ts-node line.ts
        ```
YOLOX-ROSとRealSenseで物体検出

# はじめに

Docker環境でRealSense のRGB画像を使ってYOLOX-ROSで物体検出する手順

https://github.com/Ar-Ray-code/YOLOX-ROS/tree/humble

## YOLOX-ROSについて

YOLOXをROS 2 Humbleに対応させたもの
詳細は作者のAr-Ray氏の記事を見てください。


https://ar-ray.hatenablog.com/entry/2021/07/28/040521


https://ar-ray.hatenablog.com/entry/2023/07/23/235817





# 動作確認環境

| 項目 |	値 |
|:--|:--|
| CPU | Intel® Core™ i7-12700H |
| GPU | GeForce RTX 3050 Ti Mobile |
| Ubuntu | 22.04 |
| Kernel | 6.2.0-36-generic |
| docker |  24.0.6 |
| docker compose | v2.21.0 |


# YOLOX-ROSのDockerイメージの作成



https://github.com/Ar-Ray-code/YOLOX-ROS/tree/humble/yolox_ros_cpp/docker/onnxruntime

こちらのonnxruntimeのDockerfileとdocker-compose.ymlを使う　（Tensor RT, OpenVINOは動作未確認）
docker コンテナ内でRealSenseにアクセスできるように docker-compose.ymlに以下を追加
```
        privileged: true
```



ワークスペースに移動して、YOLOX-ROSのリポジトリをクローンします。

```
cd ~/ros2_ws/src
git clone --recursive https://github.com/Ar-Ray-code/YOLOX-ROS -b humble
cd YOLOX-ROS/yolox_ros_cpp/docker/onnxruntime/
```

Docker イメージの作成

```
docker compose up --build
```

Dockerコンテナに入って、YOLOX-ROSのセットアップ

```
docker exec -it yolox_onnxruntime bash
cd ~/ros2_ws
./src/YOLOX-ROS/weights/onnx/download.bash all
source /opt/ros/humble/setup.bash
colcon build --cmake-args -DYOLOX_USE_ONNXRUNTIME=ON
```

サンプルの実行

```
ros2 launch yolox_ros_cpp yolox_openvino.launch.py
```

# RealSenseで動かす

コンテナ内にlibrealsense とrealsense_ros のインストール

```
sudo apt update
sudo apt install ros-humble-librealsense2 ros-humble-realsense2-camera
```

realsense-rosとYOLOX-ROSの実行　

```
ros2 launch realsense2_camera rs_launch.py
ros2 launch yolox_ros_cpp yolox_onnxruntime.launch.py src_image_topic_name:="/camera/color/image_raw"
```

model を変更する場合　（デフォルトはyolox_tiny）

```
ros2 launch yolox_ros_cpp yolox_onnxruntime.launch.py src_image_topic_name:="/camera/color/image_raw" model_path:='./src/YOLOX-ROS/weights/onnx/yolox_m.onnx'
```
Database操作#DELETE編

# DELETE文
`DELETE`は`crud`の`Delete`にあたるもの
### 基本
#### 使用方法
```sql
DELETE FROM table_name;
```
`WHERE`で条件指定できる
***
### table:user
|name|age|gender|address|
|:---:|:---:|:---:|:---:|
|john|23|male|Tokyo|
|james|15|male|Osaka|
|robert|20|male|Tokyo|
|michael|32|male|Fukuoka|
|william|18|male|Tokyo|

`address`が`Tokyo`の人を**削除**
```sql
DELETE FROM user WHERE address = 'Tokyo';
```
`age`が20未満の人を**削除**
```sql
DELETE FROM user WHERE age < 20;
```
`name`がjから始まる人を削除
```sql
DELETE FROM user WHERE name LIKE 'j%';
TypeError: 'numpy._DTypeMeta' object is not subscriptable

# 環境
M1 (arm64) / macosx(14.0) / python 3.10 / venv環境

# 問題
import cv2 を実行時、次のエラーが出た
`TypeError: 'numpy._DTypeMeta' object is not subscriptable`

# 解決法
```
pip uninstall numpy
pip install numpy
```

で治ります。

(ubuntuとかだったかだったら、https://github.com/cvg/LightGlue/issues/69 らしい）
ICCV2023の量子化論文 (1)

# 概要

この記事では、[ICCV2023](https://iccv2023.thecvf.com/)の量子化論文を紹介します。[^1]

[^1]: 画像や数式は論文から引用しています。


# Jumping through Local Minima: Quantization in the Loss Landscape of Vision Transformers

https://openaccess.thecvf.com/content/ICCV2023/papers/Frumkin_Jumping_through_Local_Minima_Quantization_in_the_Loss_Landscape_of_ICCV_2023_paper.pdf

- 概要：Eval-Q. ViTの量子化の鋭敏さの改善
- 研究機関：ARM
- 新規性：ViTの量子化の特性に、量子化スケール対精度やロスの鋭敏さがあることを指摘し、対策
- キモ：Contrastiveロスを入れてロスを滑らかにし、進化的アルゴリズムで最適化する。


# Unified Data-Free Compression: Pruning and Quantization without Fine-Tuning

https://openaccess.thecvf.com/content/ICCV2023/papers/Bai_Unified_Data-Free_Compression_Pruning_and_Quantization_without_Fine-Tuning_ICCV_2023_paper.pdf

- 概要：UDFC. データ無し枝刈り、量子化
- 新規性：データ無し枝刈りと量子化を同時にする


# EMQ: Evolving Training-free Proxies for Automated Mixed Precision Quantization

https://openaccess.thecvf.com/content/ICCV2023/papers/Dong_EMQ_Evolving_Training-free_Proxies_for_Automated_Mixed_Precision_Quantization_ICCV_2023_paper.pdf

- 概要：混合量子化の学習なし最適化
- 新規性：混合量子化の評価尺度(Proxy)の探索空間をActivation, Gradient, Weight, Hessianから選ぶ。(Fig. 1)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/7278db91-bcb2-82e3-ba7f-b077e0af04f1.png)


# DenseShift : Towards Accurate and Efficient Low-Bit Power-of-Two Quantization

https://openaccess.thecvf.com/content/ICCV2023/papers/Li_DenseShift_Towards_Accurate_and_Efficient_Low-Bit_Power-of-Two_Quantization_ICCV_2023_paper.pdf

- 概要：Shift Network (かけ算の代わりにビット演算を使う)の精度改善
- 研究機関：Huawei
- 新規性：低ビットShift Networkの精度改善
- キモ：ゼロ重みは結果に寄与しないので、ゼロが起こらないようシフトする仕組みを入れた。(2)式、Fig. 3.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/7a864327-42b0-44a9-c3fd-8fb4c1f096a2.png)


# EQ-Net: Elastic Quantization Neural Networks

https://openaccess.thecvf.com/content/ICCV2023/papers/Xu_EQ-Net_Elastic_Quantization_Neural_Networks_ICCV_2023_paper.pdf

- 概要：どのようなデバイスでも精度の良いDNNの探索。
- 新規性：NVIDIAやQualcommで量子化方法が違うことを指摘し、どのような用途でも精度の良いDNNを探索する。Fig. 1.
- キモ：(3)式でどのような条件にも合わせて最適化。量子化条件をMLPで精度を予測してGAで探索。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2448931/ef14ec14-53b9-100f-5ea1-aec0f3e379a9.png)
replace/re.subで文字列変換

# はじめに
Pythonの文字列変換について、replaceとre.subについてまとめる。

# 目次
+ [replace](#replace)
+ [re.sub](#resub) 
  + [re.sub 基本](#基本)
  + [re.sub flags](#flags)
  + [re.sub 応用](#応用)
+ [正規表現](#正規表現)


## replace
**replace(old, new, count=0)**
```old```から```new```へ変換する。```count```は変換する最大回数。初期値は0で回数関係なくすべて変換する。
```python:replace_sample.py
# ABCを___に変換
s = 'ABCDEFABCDEF' 
s = s.replace('ABC','___',)
print(f'# {s=}')
# s='___DEF___DEF'

# count=1で1回変換
s = 'ABCDEFABCDEF' 
s = s.replace('ABC','___',1)
print(f'# {s=}')
# s='___DEFABCDEF'
```
[戻る](#目次)

## re.sub
正規表現を使用して変換する方法。reモジュールをimportして使用する。
**re.sub(pattern, repl, string, count=0, flags=0)**
```string```が変換対象の文字列で、```pattern```に合致したものを```repl```へ変換する。```count```は変換する最大回数。初期値は0で回数関係なくすべて変換する。

### 基本
```pattern```と```repl```を正規表現で表す場合は **r**を付ける。```pattern```を```()```で括るとグループ化される。グループ化されたパターンを```repl```で再利用する場合は```\1,\2,...(数値がグループの順番)```で指定する。
```python:resub_sample.py
# 数値を_に変換。正規表現を使う場合は r を付ける
s = 'ABCabc123@python.com' 
s = re.sub(r'\d', '_', s)
print(f'#{s=}')
#s='ABCabc___@python.com'

# グループの一つ目を抜き出す。
s = 'ABCabc123@python.com' 
s = re.sub(r'(.*)(@)(.*)', r'\1', s)
print(f'#{s=}')
#s='ABCabc123'
```
[戻る](#目次)

### flags
flagsを使うと、検索パターンを拡張できる。

flags|内容
---|---
re.ASCII|ASCII文字だけマッチ。
re.DOTALL|. を改行を含む任意の文字にマッチ。
re.IGNORECASE|大文字小文字を区別しないマッチ。
re.MULTILINE|複数行文字列に対して、^ と $ を各行でマッチ。

複数行の```^先頭```、```$終端```一致の場合は、```re.MULTILINE```を使うと便利。
```python:resub_sample.py
s = 'ABCabc123@python.com\nABCabc123@python.com\nABCabc123@python.com\n' 
s = re.sub(r'^ABC', '___', s)
print(s)
# ___abc123@python.com
# ABCabc123@python.com
# ABCabc123@python.com

# re.MULTILINEを有効にする
s = 'ABCabc123@python.com\nABCabc123@python.com\nABCabc123@python.com\n' 
s = re.sub(r'^ABC', '___', s, flags=re.MULTILINE)
print(s)

# ___abc123@python.com
# ___abc123@python.com
# ___abc123@python.com
```
[戻る](#目次)

### 応用
複雑な変換をしたい場合```repl```を関数化することもできる。```group(1)```は```\1```に等しい。

```python:resub_sample.py
# 変換関数
def converter_func(match):
	print(f'# {match=}')
	print(f'# {match.group(0)=}')
	print(f'# {match.group(1)=}')
	print(f'# {match.group(2)=}')
	print(f'# {match.group(3)=}')
	ret = f'# User:{match.group(1)} / Domain:{match.group(3)}'
	return  ret

s = 'ABCabc123@python.com' 
s = re.sub(r'(.*)(@)(.*)', converter_func, s)

print(s)

# match=<re.Match object; span=(0, 20), match='ABCabc123@python.com'>
# match.group(0)='ABCabc123@python.com'
# match.group(1)='ABCabc123'
# match.group(2)='@'
# match.group(3)='python.com'

# User:ABCabc123 / Domain:python.com
```
[戻る](#目次)



## 正規表現
正規表現一覧。

正規表現|内容
---|---
\d|任意の数字
\D|任意の数字以外			
\s|任意の空白文字			
\S|任意の空白文字以外			
\w|任意の英数字			
\W|任意の英数字以外
.|任意の一文字
^|文字列の先頭  **^abc (abcで始まる)**
$|文字列の末尾  **abc$ (abcで終わる)**
*|０回以上の繰り返し
+|１回以上の繰り返し
?|０回または１回
{m}|m回の繰り返し
{m,n}|m〜n回の繰り返し
\||or
[]|or  **[abcdef] (a,b,c,d,e,fのどれか)**
()|グループ化

[戻る](#目次)

以上
【来年の目標】2019年ごろに作ったRuby/TKアプリ javascriptで作り直したい（2024年中）

javaspcriptの勉強のモチベーションとして
2019年ごろに作ったRuby/TKアプリ をjavascriptで作り直したい
javaspcript + HTML + css 
HTA っていうんですかね？

機能 
・指定条件でファイルを検索して登録。（ベースディレクトリ、拡張子、含むワード、無視ワード） 
・拡張子別に指定したプログラムに渡して実行。
・実行時間、実行回数を記録。 
・ランダムソート、ランダム実行。 
・ファイルの移動、リネームを自動検出して実行時間回数などのデータも移行

※開発当時の環境 今はこのバージョンはもうないので自分でruby/TK環境を用意する必要あり 
WITHOUT DEVKIT Ruby 2.3.3 ※32ビット 
Ruby 2.3.3 (x64) ※64ビット

git hub
https://github.com/majimiki/rubytktest/blob/main/_Random_Launcher.rbw
企業間エンジニア交換留学を実施しての学び

株式会社エイチーム（以下エイチーム）とサイボウズ株式会社（以下サイボウズ）で在籍型出向によるエンジニアを交換留学する取り組みを実施しました。
今年で2回目の取り組みとなり、今年は自分が株式会社エイチームからサイボウズ株式会社へ出向となり、2023年10月の1ヶ月間サイボウズ株式会社で仕事をしておりました。
本記事では、この1ヶ月の取り組みをしてみてどうだったかの学びをアウトプットする記事です。
※ 公には細かいところまではアウトプットしませんので、どうしても一般的な話になってしまうことはご容赦ください

第一回目（2022年）のときのプレスリリースは以下です
https://www.a-tm.co.jp/news/34656/

# 交換留学の目的確認

- 自身の視野や知見を広げること
- 良いところを持ち帰って普段の業務に活かすこと
- 自身の強み・弱みを肌で感じ、今後のチームの活動方針を考える際の参考にすること

## **「自身の視野や知見を広げること」に関して**
エイチームではEMという立場で仕事をしています。
今回はEMという立場がなくなり、プレイヤーとしてジョインさせていただくことで普段ではない視点から見ることができたと思います。
その中で、エイチームの強みやサイボウズの強み、様々な情報を俯瞰して見ることができたと思います。

新卒でエイチームに入社して9年目、周りから見るとベテランの部類になるかと思います。
何かを行動する際はそれが当たり前だと思ってしまいますし、何かが起こったときはなんとなく対処法も想像できてしまいます。
その固定概念が自身の幅を狭めてしまっているなと今回気づきました。

## **「良いところを持ち帰って普段の業務に活かすこと」に関して**
サービス基盤に対する考え方や、仕事の進め方、等々良いところは色々吸収できたと思います。

現在、エイチームに戻って働くにあたって、サイボウズで学んだことを早速チーム内で実践しております。
しっかりと会社に還元できるように、いいものはどんどん広げて行きたいと思い舞ます。

## **「自身の強み・弱みを肌で感じ、今後のチームの活動方針を考える際の参考にすること」に関して**
自身の強みとしては、「行動力」「コミュニケーション力」「スクラムマスターの経験」かと思っています。
今回サイボウズに入って改めて自分の強みを認識できたかと思いました。

ちなみに、自身が感じていた、思っていた弱みは実は「アウトプット力」です。
今回は強制的にアウトプットしないと行けない場に自ら飛び込むことで、多くアウトプットすることを自分に課していました。
質が高いアウトプットができたかと言うとまだまだだな・・と課題に思うところは多くありましたが、アウトプットができたかと思います。


# 交換留学でやるべきこと

- サイボウズで関わってくれた方々に対して刺激を与えること
- エイチームの成長のヒントとなることを持ち帰り共有を行うこと
- サイボウズでできた人脈を活用していくこと

エイチームのことをアウトプットしつつ、様々な人に考えるきっかけやヒントをお渡しできたかなと思います。
ただ、1ヶ月という短い期間ということもあり、アウトプットして終わりというところで止まってしまったものもあったかと思います。
更にそこから改善を繰り返し、成果が出るところまでやりたかったです。

# チームでやったことの紹介

ざっくりとしたスケジュールは以下となります。

- オンボーディング（1.5営業日）
- 製品チームに配属され、チーム内で開発①（8営業日）
- 製品チームに配属され、チーム内で開発②（8営業日）
- まとめ期間（2営業日）

製品チームは2つのチーム体験に参加したため、隔週で違うチームに配属された形となります。
上記以外にも、他チームとの交流や1on1、LT大会、社内MTGなど、色々な経験をさせていただきました。

# 会社や事業についての学び

前提として、どっちが良くて、どっちが悪いかというものはないと思います。
サイボウズ、エイチームそれぞれ事業、組織文化、人が異なるので色が違うのは当たり前のことだと思います。

その中でも、ビジネスモデルの違い、要するにサービス（製品）や収益基盤の違いから、組織の文化や人の考え方、動き方が異なるなということが全体通して感じたところです。

エイチームしか知らない自分は他のサービスや組織風土を知ることはとても貴重な経験でした。

# 結び

1ヶ月は本当にあっという間でした・・！そして、とても濃い1ヶ月を過ごせました！
今回の交換留学を実施するに辺り、事前準備や受け入れ体制を作ってくれたエイチームならびにサイボウズの方々には大変感謝しております。
自身が1ヶ月間、楽しく仕事ができたのもみなさんのおかげだと思っています。

今回の交換留学は視野や知見を広げる機会としてはとても良く、自分の仕事人生の中でも価値のある1ヶ月でした。
（なによりも1ヶ月という短い期間で自身の求められているレベルのものをアウトプットするというミッションがあるので、1日1日がとても濃かったです。）
今回刺激を受けた分、それをきちんと自分で終わらさせるのではなく還元できるようにしていきたいと思います。

是非こういう取り組みを色々な方に知ってもらい、自分たちもやってみたい！と声があがるといいなと思います。
Turbo Stream使用時はcurrent_userの情報を渡せない、ではどうするか

# はじめに
本記事は錆びかけたRailsの知識を頑張ってアップデートするアドベントカレンダー22日目です。

今回は、リアルタイムメッセージ送信機能の実装を考えます。

この時、UIはLINEのように自分のメッセージと他の人のメッセージとの区別がつくような形を想定します。

![feuwafeway_.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/65439/58d3f503-66e6-aa7d-0e75-95784183fc97.png)
画像引用:https://linecorp.com/ja/pr/news/ja/2020/3520

# 課題
こちらは参考にした記事に詳しいのですが、turbo streamを利用したfetchで部分テンプレート部分を更新する場合、`current_user`を利用することができません。

# 解決方法
更新したメッセージが`current_user`のものかどうかは、Stimulusを使って別途伝える必要があります。

その際、以下のようにログインしているユーザーのidをbodyタグに仕込み、Stimulusに渡すようにします。

```erb:application.html.erb
<!-- app/views/layouts/application.html.erb -->
<body data-controller="application" data-application-user-id-value="<%= current_user.id if user_signed_in? %>">
  <%= yield %>
</body>
```

bodyタグに仕込んだcurrent_userのidは、Stimulusのコントローラで以下のように取得できます。

```javascript:application_controller.js
// app/javascript/controllers/application_controller.js
import { Controller } from "@hotwired/stimulus"

export default class ApplicationController extends Controller {
  // 共通のメソッドや値を定義
  static values = { userId: Number }
}
```

このコントローラを継承した別のコントローラを作ると、current_userの値が共通化できてよさそうです。

```javascript:message_controller.js
// app/javascript/controllers/message_controller.js
import ApplicationController from "./application_controller"

export default class extends ApplicationController {
  connect() {
    if (this.userIdValue === Number(this.element.dataset.userId)) {
      // 現在のユーザーによるメッセージの場合の処理
    } else {
      // それ以外の場合の処理
    }
  }
}
```

あとは、リアルタイム通信時にブロードキャストされる部分テンプレートをStimulusで捕捉し、接続されたタイミングで左右に出し分けるCSSを当てるようにすればよさそうですね。

```erb:_message.html.erb
<!-- app/views/messages/_message.html.erb -->
<div id="message_<%= message.id %>"
     class="message <%# デフォルトは左側に表示 %>"
     data-controller="message"
     data-message-user-id-value="<%= message.user.id %>">
  <!-- メッセージの内容 -->
</div>
```

# 終わりに
今回はRails側のコントローラ部分や、HotWireによるリアルタイム通信の部分は触れなかったので、機会があればその辺もまとめて実装方法として公開したいですね。

# 参考
こちらの記事を参考にさせていただきました。

https://goodenough.us/blog/2023-08-02-til-turbo-stream-and-personalised-content/
typeormをv0.2からv0.3にアップグレードしてみた

## 変更差分
https://github.com/IsaUmetsu/baseball/pull/27

### 変更概要(抜粋)
- `import { createConnection, getConnection, Connection, getRepository, getManager } from 'typeorm';` が廃止
    - createConnection, getConnection, Connection -> `import { DataSource } from 'typeorm';`
    - getRepository -> `import { AppDataSource } from './datasource';` した上で、`AppDataSource.getRepository` とする
    - getManager -> `await AppDataSource.manager`
    -
paiza.ioでelixir その274

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
マップなリストに、CRUDを施せ。

# 方針
- リストを使い廻す。
- idを使う。
- Enum.with_index使う。

# サンプルコード

```


defmodule Ecto2 do
    def insert(db, v) do
        db = db ++ [v]
    end
    def update(db, v) do
	    i =	Enum.filter_map(Enum.with_index(db), fn {x, _} -> 
			x.id == v.id 
		end, fn {_, i} -> 
			i 
		end)
		|> Enum.at(0)
        db = List.replace_at(db, i, v)
    end
    def delete(db, v) do
        db = List.delete(db, v)
    end
    def print(db) do
        Enum.map(db, fn x -> 
        	[ x.id,  x.name]
        end)
        |>IO.inspect
    end
end

db = [
  %{
    id: 1,
    name: "ryu",
    age: 10,
    gaku: "s"
  },
  %{
    id: 2,
    name: "ryo",
    age: 20,
    gaku: "s"
  },
  %{
    id: 3,
    name: "alice",
    age: 20,
    gaku: "s"
  },
  %{
    id: 4,
    name: "kent",
    age: 30,
    gaku: "s"
  }
]

Ecto2.print(db)
db = Ecto2.insert(db,   %{
    id: 5,
    name: "kent",
    age: 30,
    gaku: "s"
  }
)
Ecto2.print(db)

db = Ecto2.delete(db,   %{
    id: 5,
    name: "kent",
    age: 30,
    gaku: "s"
  }
)
Ecto2.print(db)

db = Ecto2.update(db,   %{
    id: 1,
    name: "yoko",
    age: 30,
    gaku: "s"
  }
)
Ecto2.print(db)




```

# 実行結果

```
[[1, "ryu"], [2, "ryo"], [3, "alice"], [4, "kent"]]
[[1, "ryu"], [2, "ryo"], [3, "alice"], [4, "kent"], [5, "kent"]]
[[1, "ryu"], [2, "ryo"], [3, "alice"], [4, "kent"]]
[[1, "yoko"], [2, "ryo"], [3, "alice"], [4, "kent"]]

```

# 成果物

https://paiza.io/projects/W9FSEDOx7wmAC6On4rnUew


以上。
個人ゲーム開発・TRPG関連のOSS


https://qiita.com/Subara3/items/c6874fe04504fa7148b3

上の記事でAdvent Currenderに参加したついでに、「身近で自分がお世話になっているOSSって何があるのかな～」と思ってリストアップしてみました。
私の趣味です。

# TRPG関連

## BCDice
https://github.com/bcdice/BCDice

Discordのダイスボットや、各セッションツールで使用されているダイスシステム、BCDice。

## ユドナリウム

https://github.com/TK11235/udonarium

セッションツール、ユドナリウムはオープンソースです。
カードの操作がしやすく、インセインやマーダーミステリーでお世話になっています。

# ゲーム制作関連

## godot
https://github.com/godotengine/godot

これは大きいところ、ゲームエンジンgodotはオープンソースです。

## ティラノスクリプト
https://github.com/ShikemokuMK/tyranoscript

ノベルゲームエンジンティラノスクリプトもオープンソース（MITライセンス）でした。

## 吉里吉里Z
https://github.com/krkrz/krkrz

吉里吉里Zもオープンソース！

# その他

## misskey
https://github.com/misskey-dev/misskey

分散型SNS、misskeyはオープンソースです。
AtCoder Beginner Contest 333 振り返り

# ABC333
## 概要
実力的には二年前に茶色になって放置して暫くぶりの参加なので詳しい解説などは期待しないでもらえると。
同じぐらいの初心者さんがこんな感じで解いたのかぁ的な見方か、上級者の方が愉悦として見ていただけると幸いです。

https://atcoder.jp/contests/abc333

コンテスト中に触ることができたのはA,B,C問題。ACできたのはC問題までです。
触れた問題で解説を見て理解できたものについては振り返っていきたいと考えています。

## A - Three Threes
__考えてたこと__
見たまま実装するだけ。

__提出したもの__
```c++:a.cpp
int main() {
    int n;
    cin >> n;
    rep(i,0,n){
        cout << n;
    }
    return 0;
}
```

__振り返り__
特になし。

## B - Pentagon
__考えてたこと__
長さとかはよくわからないけど、隣同士なら同じ距離だし、二つ隣の点同士なら同じ距離だし、みたいな感じをなんとなくコードで表現。そしたら隣の辺の距離を1ではなく4と計算してしまっていてWA。
min(5-num1, num1)の部分を追加してAC。

__提出したもの__
```c++:b.cpp
int main() {
    map<char, int> map;
    map['A'] = 0;
    map['B'] = 1;
    map['C'] = 2;
    map['D'] = 3;
    map['E'] = 4;

    char s1, s2, t1, t2;
    cin >> s1 >> s2 >> t1 >> t2;

    int num1, num2;

    num1 = abs(map[s1] - map[s2]);
    num2 = abs(map[t1] - map[t2]);

    num1 = min(5-num1,num1);
    num2 = min(5-num2,num2);

    if (num1 == num2) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }

    return 0;
}
```
__振り返り__
1WAしたのが反省。

## C - Repunit Trio
__考えてたこと__
最初は数学的なパターンを見つけようとして時間の無駄遣い、次に全パターンの列挙をしようと思って実装を失敗しまくって時間の無駄遣い。

__提出したもの__
```c++:c.cpp
ll calculate_repunit(ll n) {
    ll repunit = 0;
    while (n > 0) {
        repunit = repunit * 10 + 1;
        n--;
    }
    return repunit;
}

int main() {
    ll n;
    cin >> n;

    vector<ll> vec(20);
    rep(i, 1, 13) {
        vec[i] = calculate_repunit(i);
    }

    set<ll> set;

    rep(i, 1, 13) {
        rep(j, i, 13) {
            rep(k, j, 13) {
                ll sum = vec[i] + vec[j] + vec[k];
                set.insert(sum);
            }
        }
    }

    ll count = 0;
    for (auto it = set.begin(); it != set.end(); ++it) {
        count++;
        if (count == n) {
            std::cout << *it << std::endl;
            break;
        }
    }
    return 0;
}
```


__振り返り__
時間寸前までこの問題で止まっていました。
全探索できそうな時は素直に全探索をする癖をつけた方が良いかも。
あと、入力例に制約上限の333があることを気づかなくて、出力の上限の桁数を無駄に長くして実装ミスを起こしていたのも反省。

## 総括
- もっと用心深く。

## 感想
二週間前だからあまり覚えていないけどC問題ですごく苦労して大変だったことだけ覚えています。
![Screenshot 2023-12-24 at 14.40.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396642/431e01ea-c315-58c8-ba86-f88c1eac5288.png)
1万ダウンロードのバスアプリを運営している話

:::note info
この記事は[watnow アドベントカレンダー](https://qiita.com/advent-calendar/2023#participating_calendar)の24日目の記事です
:::

# はじめに
busdes!という立命館大学びわこ・くさつキャンパス、衣笠キャンパス向けのバス時刻表アプリbudes!を運営している、立命館大学B4のマーシーです。 [watnow](http://www.watnow.jp/) という学生IT団体に所属しています。

busdes!のiOSアプリのダウンロード数は約1万です。このアプリは、Backend,iOS,Androidで構成されていますが、自分はBackendの開発をしただけで,iOS,Androidに関しては先輩方や友達が開発したものを使用しています。

[びわこ・くさつキャンパス向けのアプリ](https://ritsumeikanunivpress.com/07/11/4430/)は今のバージョンになってから既に3年以上が経過しています。

私は、昨年このアプリの運営を卒業された先輩から引き継ぎました。

# 現状
現状、追加の開発は一切行っておらず、宣伝も春にTwitterで少ししている程度です。アプリ自体は、口コミで広がりバス通学をしている学生のほとんどが使っているアプリになっています。

# アプリの概要
[京都産業大学の時刻表アプリ](https://qiita.com/kitsune_yk/items/0ed01715be487ad5c921)では、事前にバス会社から取得した時刻表を、表示しているようです。

busdes!も、バス会社が発表している時刻表を表示していることは同じなのですが、開発者がいなくてもサービスが継続できるように、バス会社の時刻表ページをスクレイピングすることで時刻表を表示しています。バス会社に確認を行った上で、1日1回のみスクレイピングを行なっています。

また、busdes!には、バスの遅れ情報を表示する機能もあります。これは、バス会社が提供している遅れ情報をスクレイピングし表示しています。これは、リアルタイムな情報更新が求められるので、リクエストごとに行っています。

https://apps.apple.com/us/app/busdes-%E3%83%90%E3%82%B9%E3%81%A7%E3%81%99/id1491015874?l=ru

https://play.google.com/store/apps/details?id=busdes.rits.jp&hl=ja&gl=US

# 運営の問題
## サーバコストの問題
通常、学生が大量の人に使われるアプリケーションを運用しようと思うと少なくとも月数千円程度のサーバ代がかかります。busdes!も昨年までは、月1万円ほどのサーバ代がかかっていました。しかし、アプリからの広告収入では賄えないためサーバ代を下げる必要がありました。

元々、GCPの[App Engin](https://cloud.google.com/appengine?hl=ja)を使用していましたが、[Cloud Run](https://cloud.google.com/run?hl=ja)に変更し、水平スケーリングするように設定することでコストを削減しました。結果的にサーバ代は月50円程度になりました。


サーバコストの問題は解決され運営しやすいアプリになりました。

## 開発コスト
[京都産業大学の時刻表アプリ](https://qiita.com/kitsune_yk/items/0ed01715be487ad5c921)は1時間できたようですが、busdes!は1時間とかでできるものではありません。


iOS,Android,Backendを合わせると100時間は余裕でかかっているようなアプリです。なかなか、追加機能を開発するにも先輩方が書かれたコードを読んで直すという大変な作業をしなければなりません。

リッチなアプリが逆にこのアプリの負債とも言えるかもしれません。課題解決のために必要以上にリッチなアプリを作ってしまうと、その後の運営が大変になるというのを肌で感じています。

学生の中での開発の流行りも今どちらかというと、iOSやAndroidアプリではなく、Next.jsなどのWebアプリです。また、Flutterなどのクロスプラットフォームも流行っています。busdes!はiOSはSwift storyboard、AndoidはKotlinとXMLで開発されています。2023年現在、iOSはSwiftUI、AndroidはComposeが主流になってきており、学生の興味もそっちに向いています。

フルリプレースはかなりコストが高く、レガシーのコードをやりたい学生も少ないです。学生が開発、運営するアプリでは、技術の移り変わりがかなりはやく、同じコードベースでの開発を長期間続けるのは困難です。

# 運営の面白さ
## 技術的な面白さ
このメトリクスを見て分かる通り、瞬間的には2req/sを超えるリクエストが飛んできます。Cloud Runの水平スケーリングが働いて、2台,3台とコンテナインスタンス数が増えていく様子が見れます。ただ、少しスクレイピングをするくらいでは、Goで作られたサーバはCPU,メモリへの負荷がかからず、瞬間的にコンテナが死んだ時にもう1台が立ち上がるくらいですが、、、。
`リクエスト数の推移`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128363/8a12efc3-bbcd-089e-9eee-191ec9f6fdde.png)`
コンテナ数の推移`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1128363/fb617280-5df9-1f4c-e67c-e27425aee350.png)


## 運営者としての面白さ
運営者としては、大学にバスで通学している人なら大体の人がbusdes!を知っているので話の種になったりします。大学と連携したり、地域と連携したり色々話は広がるとは思うのですが、どうしても開発コストを考えると身動きが取りづらくなっているのが現状です。


# アプリの今後
立命館大学びわこ・くさつキャンパスから、情報理工学部は移転することが決まっており、来年からは通学していないキャンパスのバスアプリを運営していくことになります。また、自分もあと2年すれば就職です。近いうちに後輩にバスの運営を交代して後輩たちに、busdes!をもっと良いものにしてほしいなと考えています。
Linuxでipv6を無効化してipv4通信を優先したい

# 環境情報
* MIRACLE LINUX release 8.9 

# ipv6が優先されていることを確認
```
# ping localhost
PING localhost(localhost (::1)) 56 data bytes
64 bytes from localhost (::1): icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from localhost (::1): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from localhost (::1): icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from localhost (::1): icmp_seq=4 ttl=64 time=0.025 ms
```
# grub設定でipv6を無効化
<font color="red">**ipv6.disable=1**</font>を追加
```
# vim /etc/default/grub 
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
GRUB_DEFAULT=saved
GRUB_DISABLE_SUBMENU=true
GRUB_TERMINAL_OUTPUT="console"
GRUB_CMDLINE_LINUX="crashkernel=auto resume=/dev/mapper/ml-swap rd.lvm.lv=ml/root rd.lvm.lv=ml/swap rhgb quiet ipv6.disable=1"
GRUB_DISABLE_RECOVERY="true"
GRUB_ENABLE_BLSCFG=true
```
# grubファイルの設定反映
```
# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ...
done
```
# サーバ再起動
```
# reboot
```

# ipv4が優先されていることを確認
```
# ping localhost
PING localhost(localhost (127.0.0.1)) 56 data bytes
64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.106 ms
64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.042 ms
64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.025 ms
```
Livebook でテキストの差分を抽出する

## はじめに

Livebook でテキストの差分を抽出し、ハイライトして表示します

実装したノートブックはこちら

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/kino/kino_diff.livemd

## セットアップ

```elixir
Mix.install([
  {:kino_diff, "~> 0.1.0"}
])
```

KinoDiff をインストールします

https://github.com/NduatiK/kino_diff

## 差分抽出

差分抽出したいテキストを指定します

まずは `layout: :inline` のオプションを指定してみましょう

```elixir
KinoDiff.new(
  """
  こんにちは

  今年も残すところあと7日ですね

  """,
  """
  こんばんは

  今年も残すところあと6日ですね

  """,
  layout: :inline
)
```

実行結果

![スクリーンショット 2023-12-24 14.15.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/a0fecb2e-bb49-87af-2ffa-659660200305.png)

変更前が赤、変更後が緑でハイライトされました
変更前については取り消し線もついていますね

では `layout: :split` のオプションを指定してみましょう

```elixir
KinoDiff.new(
  """
  こんにちは

  今年も残すところあと7日ですね

  """,
  """
  こんばんは

  今年も残すところあと6日ですね

  """,
  layout: :split
)
```

実行結果

![スクリーンショット 2023-12-24 14.17.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/faa41108-7bfd-f553-2be8-67900682c688.png)

左右に変更前後が分かれて表示されました

## まとめ

単純な機能ですが、 Livebook の視覚化をうまく活かしていますね
軽深演習 #19 数学

### 軽深（かるしん　なんちゃって圏論） Advent Calendar 2023 19日目の記事です。

演習形式をとっているので、ぜひ　回答を試みてください。

### 前提知識　数学は、絶対的に正しい
一度証明されれば、数学の定理は永遠に正しいです。ピタゴラスの定理がそうですね。永遠に絶対的に正しいことは通常の科学ではないです。
計算は、事前に実際の作業で確かめなくても可能を判断できます。２ミリのネジ穴には３ミリのネジをいれてみても、はいりません。数学って結構すごいことなんです。

図式で書くと、こんな感じですね。射の合成です、
```mermaid
flowchart LR
A[ネジがあわない]-->B[実際にいれてみる]-->C[はいらないが結論]
A[ネジがあわない]--計算-->C[はいらないが結論]
```
実際の作業を行わなくても結果は、わかります。計算は、非常に便利です。もっと複雑な事例は、シミュレーションと呼びます。正確なシミュレーションできれば非常に役に立ちます。
さて、この計算の部分をもう少し解像度をあげた図式にしてみましょう。
こんな図式になっていませんか？
```mermaid
flowchart LR
A[脳内だけ]-->B[手作業]-->C[計算実行]
```
メモをとったり、パソコンを使ったりする前に脳内だけで考えることをしませんか？　勿論、いきなり作業を開始することもあるでしょうけど、
ソフトは、複雑になると脳内でイメージトレーニングしてから、行うのが効率的です。そのことについて書かれた本があります。[３Ｄ-ＣＡＤのための立体把握トレーニング: 脳内３Ｄ化](https://amzn.to/4aBL03N)。脳内シミュレーションは、かなり高性能ではないでしょうか？　[そろばん](https://www.ishido-soroban.com/matome/118/)もすごいですね。

というわけで、脳内シミュレーションをしてみませんか？　

### 演習 失敗続きのマイナンバーの企画会議の様子を脳内だけで想像してみましょう。さらに健康保険証廃止にともなうトラブル洗い出しの会議も想像しましょう。

脳内シュミレーションはイメージトレーニングと同じようなものです。さらに発展させると[明晰夢](https://ja.wikipedia.org/wiki/%E6%98%8E%E6%99%B0%E5%A4%A2)のように、寝ている時も脳を効率よく使うことができるかもしれません。軽深（かるしん　なんちゃって圏論）で図式を使って考えるだけでも、面白い発想が得られる気がしませんか？
Salesforce でE2E専用のMFA未設定ユーザーを作成する

# はじめに

Autify等のE2E製品でSalesforceをテストする場合に
MFAが有効になっていると別途MFAを突破するための処理を書かなければいけません。

Salesforceでは、E2Eで使いたいみたいなユースケースに対応するため
一部ユーザーをMFA対象から除外する設定が用意されています。

https://help.salesforce.com/s/articleView?id=sf.security_mfa_exclude_exempt_users.htm&type=5

# やること

- システム権限`除外ユーザーの多要素認証を放棄`を付与
- すでに認証アプリが登録されている場合は切断する


# 書かないこと

- Autifyの設定、テスト

# システム権限`除外ユーザーの多要素認証を放棄`を付与

## 1. 権限セットの作成

プロファイルに設定してもいいですが、権限セットの方が今後類似のユーザーを増やす場合に管理がしやすいので
権限セットを作成します。


|表示ラベル|API参照名|
|---|---|
|System_除外ユーザーの多要素認証を放棄|System_MFA_OffUser|

![スクリーンショット 2023-12-24 13.32.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/a6e6797a-4439-3610-5afd-a695c8f73207.png)

## 2. 権限セットに`除外ユーザーの多要素認証を放棄`を付与

`システム権限`をクリック

![権限セット-Salesforce (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/26bf3ec5-eeb9-ce43-00d1-8bd9154b869d.png)

`除外ユーザーの多要素認証を放棄`にチェックを入れて保存

![スクリーンショット 2023-12-24 13.35.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/97f1416a-452a-73e2-485e-5e7e6914f202.png)

## 3. ユーザーを割り当て

割り当ての管理から対象ユーザーを割り当てます。

![権限セット-Salesforce (5).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/ddcfacca-ce13-27e4-475f-d48f9a724b00.png)

![スクリーンショット 2023-12-24 13.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/d617b3e7-05e8-417e-1efb-42ff33a0a030.png)


## 権限セットを割り当てたがMFAが有効になっている場合

### すでにMFA設定がしている場合は切断する

![ユーザー-Salesforce.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/fe3a9717-afba-84d2-01eb-9b8dca52b4fa.png)

## ログインIPアドレスを追加する

プロファイルの`ログイン IP アドレスの制限`が設定されていない場合
ログインしたことのないIPからのログインでメールでの確認コード入力が求められます。
E2Eツールでテストを実行する場合は、都度テスト環境が新しいもの起動するので確認コードが実行のたびに入力を求められてしまいます。
プロファイルのログインIPアドレスをツールに合わせた適切なものを設定するか`0.0.0.0 ~ 255.255.255.255`を設定することで解消します。

![スクリーンショット 2023-12-24 13.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/445600/6a17ab3a-4076-a5a2-81b5-b3c90a11bec2.png)

# 最後に

Salesforceでは画面フローによって業務の一部にウィザード画面が入ってきたりと
E2Eの必要性はどんどん高まっています。
Autifyのようなツールを導入してSalesforceのE2Eテストをどんどん行っていきましょう！

https://autify.com/ja/
AtCoder Beginner Contest 334 振り返り

# ABC334
## 概要
実力的には二年前に茶色になって放置して暫くぶりの参加なので詳しい解説などは期待しないでもらえると。
同じぐらいの初心者さんがこんな感じで解いたのかぁ的な見方か、上級者の方が愉悦として見ていただけると幸いです。

https://atcoder.jp/contests/abc334

コンテスト中に触ることができたのはA,B,C問題。ACできたのはA問題だけでした...。
触れた問題で解説を見て理解できたものについては振り返っていきたいと考えています。

## A - Christmas Present
__考えてたこと__
見たまま実装。

__提出したもの__
```c++:a.cpp
int main() {
    int b,g;
    cin >> b >> g;
    if(b>g){
        cout << "Bat" << endl;
    }
    else{
        cout << "Glove" << endl;
    }
    return 0;
}
```

__振り返り__
本番中、値が等しい時どうか悩んだけど異なると書いていました。こういうところを見返さなくても良いように問題の要点を読むスキルを身に付けたい所です。

## B - Christmas Trees
__考えてたこと__
距離を計算して間に存在するツリーの本数を数えるだけかと思ったらとんでもないことになりました...。
Lの地点に存在しているツリーのカウント、LとRの間にAが存在する場合と存在しない場合、L,Rが負の場合などそういうパターンを色々考えて迷走しました。
また、最終的にC++の余りの処理の理解が浅いことも重なりWA。

__提出したもの(WA)__
```c++:b.cpp
int main() {
    ll a, m, l, r;
    cin >> a >> m >> l >> r;

    // AからRまでのツリーの本数(Aを含めない)
    ll right = (r - a) / m;
    // AからLまでのツリーの本数(L,Aを含めない)
    ll left = (l - a - 1) / m;
    ll ans = right - left;
    if(l < a && a < r){
        ans++;
    }

    cout << ans << endl;
    return 0;
}
```
__振り返り__
振り返ってみると、落ち着いて解けば解けたかもしれないし解けなかったかもしれないぐらいの認識です。

## C - Socks 2
__考えてたこと__
B問題が解けなくて焦って落ち着いて考えられなくて...と負のループで全然でした。
偶数の時は隣の足し算するだけ、奇数の時は一つ消して隣の足し算、消す場合の全探索の計算量をどのようにして減らすかというところぐらいまでは考えられましたがその後さっぱりでした。

__振り返り__
落ち着いていても累積和で計算量を減らすということは思いつかなかったような気がします...。

## D - Reindeer and Sleigh
__考えてたこと__
コンテスト中は問題を見ることすらできず翌日振り返りでのんびり見ていたらこの問題がB,Cよりよっぽど簡単じゃない...?となりました。
必要なトナカイの数Rをソート、累積和を求めて二部探索で探すだけ。

__提出したもの__
```c++:d.cpp
int main() {
    int n, q;
    cin >> n >> q;
    vector<ll> vec(n);
    fore(a, vec) cin >> a;
    vector<ll> query(q);
    fore(a, query) cin >> a;

    sort(vec.begin(), vec.end());
    vector<ll> vec_sum(n);
    vec_sum[0] = vec[0];
    for (int i = 1; i < n; i++) {
        vec_sum[i] = vec_sum[i - 1] + vec[i];
    }
    fore(a, query) {
        cout << upper_bound(vec_sum.begin(), vec_sum.end(), a) - vec_sum.begin() << endl;
    }
    return 0;
}
```
__振り返り__
B,Cよりよっぽど簡単じゃないか...と思いました。当日、順位表とか見てたら先に気づけたかも...。

## 総括
- 焦りは禁物、とはいえB,C両方解けなかったのはかなりメンタルにきました...。
- もうちょっと機転を効かせたい。

## 感想
A問題しか解けなくてかなり精神にきました...。
やっぱりもうしばらくunratedで修行をしてからratedに挑もうかなと思う今日この頃です。
パフォーマンスが低いとかレートが落ちたとかよりB問題の試行錯誤の迷走具合が見てて辛いです。
![Screenshot 2023-12-24 at 14.06.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1396642/701f2dca-078b-f41d-18b0-91bf656fa065.png)
【Git】操作いつもやってること

大規模開発もやったことない初心者なので何も知りません
ほかにいいやり方あったら教えてください

※前提としてノートPCを持ち歩くのが苦手なので(フィジカル的に...)いろいろなPCで作業することが多いです
### 共有するとき
githubを開いて当該リポジトリまで進む
↓
アップロードしたいファイルがおかれてる階層まで進む
↓
upload fileを選択しアップロードしたいファイルをドラッグアンドドロップする
↓
レビュワーを通す場合は新規でブランチを作りPullRequestを送る、通さなくていい場合はmainブランチにコミットする

### ローカルに持ってくるとき
Git Bashを開き、当該リポジトリに移動して`git pull`を実行する

以前は`git clone [url]`でやってたのですが、毎回フォルダを削除するのもめんどくさいですし`pull`のほうがいいらしいというのを聞いたので`pull`にしています

ほかにいい方法あったらコメントで教えていただけると嬉しいです
「$message->user」と「$message->user()」の違い

## はじめに
リレーションでMessageモデルに紐づけたUserの名前（nameプロパティ）にアクセスしようとしたところ、エラーが出ました。

呼び出すときに書いたコードはこちらです。

```sql
> $message->user()->name;
```


初歩的な所ですが、解決策をまとめます。

## 環境
Laravel 9.52.16

## 問題
* $messageに紐づいたUserインスタンスのnameプロパティ（名前）にアクセスしたい
* そこで「$message->user()->name;」とアクセスしたところ、次のようなエラーが出た

```sql: MySQL
> BadMethodCallException  Method Illuminate\Database\Eloquent\Collection::users does not exist.
```

Messageモデル内のuser()メソッドは次のようになっています。

```php 
public function user()
{
    return $this->belongsTo(User::class);
}
```


## 解決策
* 「$message->user->name」とする必要があります

```sql: MySQL
> $message->user->name;
```

## user()とuserの使い分け

### メソッド呼び出し（'$message->user()'）
* $message->user()はMessageモデル内のuser()メソッドの定義に従い、belongsToオブジェクト（クエリビルダー）を返します

```php 
public function user()
{
    return $this->belongsTo(User::class);
}
```
* 「クエリ」とは「where」や「orderBy」など、DBに対する処理要求のことです
* 失敗例では、クエリビルダーのnameプロパティにアクセスしようとしていたわけです
* 実際はnameプロパティはUserモデルインスタンスに存在するので、エラーが出ていました

### プロパティアクセス（'$message->user'）
* 一方$message->userはリレーションシップに関連するモデルインスタンスを返します
* この場合、Messageモデルに紐づけられたUserモデルインスタンスを直接取得することを意味します
* そのため、Messageモデルに紐づいたUserの名前などにアクセスするときに便利です

## まとめ
「$message->user()」はクエリビルダーを返すので、さらにwhere()などでレコードを絞り込んでいく際などに使用します。

対して「$message->user」は関連するUserモデルインスタンスを返すので、

直接そのモデルインスタンスの属性にアクセスする際に使用します。
ABC334の記録

# はじめに
最近競技プログラミングに取り組んでいるので、解いた問題や参加したコンテストの記録を残す。
ABCについてはA～Cまで解ききりたい。当面は茶を目指す感じで。
というわけでABC334の記録。

ユニークビジョンプログラミングコンテスト2023 クリスマス (AtCoder Beginner Contest 334)
https://atcoder.jp/contests/abc334
成績：Aのみ1完(100)

# A
数値の大小比較で分岐する。
```python:A
b, g = map(int, input().split())
if b>g:
    print("Bat")
else:
    print("Glove")
```
なお、公式解説によると三項演算子というものがあってそれが便利らしい。
```python:A'
b, g = map(int, input().split())
print("Bat" if b > g else "Glove");
```

# B
植木算。RとLの間の距離をMで割って、RにもLにも木があったら+1すればいいと思った。
```python:B
import math
a, m, l, r = map(int, input().split())
num = math.ceil((r-l)/m)
if (l-a)%m == 0 and  (r-a)%m == 0: #lにもrにもに木があるならnum+=1
    num += 1
print(num)
```
どっこいこれが8WA。
いろいろ試しているとそもそもL, Rの取り方次第で割り算の結果を切り上げる方法と結果が食い違うパターンがあることが分かった。単なる考察不足。
※$(A, M, L, R) = (1, 3, 2, 15)$など。範囲内に入る木の本数が変わらないように範囲をできるだけ広くなるようにとると間違えやすいらしい。

というわけで解説などを見てちゃんと考え直す。
結局公式解説が一番ピンときやすくて、
「R以下で一番東にある木の番号」から「Lより小さくて一番東にある木の番号」を引けば良いことになる。
別の言い方をするなら「区間内で一番東にある木の番号」から「区間の西側範囲外のうち一番東にある木の番号」を引く。
これはRをMで割った商からLをMで割った商を引くことで求まるが、Lに木があった場合はその木は範囲内にあるので1足すと良い。
```python:B'
#全体の座標を-aすることで、Mの倍数の座標にツリーが立っている状態にできる。
a, m, l, r = map(int, input().split())
l += -a
r += -a
ans = r//m - l//m
if l%m==0:
    ans +=1
print(ans)
```

# C
正しい組み合わせが残っている靴下はそれを組み合わせると奇妙さ0なのでそうすべき。よって、$A_1, A_2,…A_K$を組み合わせて奇妙さが最小になるようにする。
Kが偶数の場合は隣り合った2つずつを組み合わせていけばよいが、Kが奇数の場合は余らせる一つを決めないといけない。
ここで$A_i$と$A_{i+1}$の階差$B_i$を考えると、$B$の最大値が$B_j$のとき$A_j$か$A_{j+1}$のいずれかを余らせるのが最適。
$B_j+B_{j+1}$と$B_{j-1}+B_j$を比較し、前者が大きければ$A_j$、後者が大きければ$A_{j+1}$を消す。
```python:C
n, k = map(int, input().split())
A = list(map(int, input().split()))
if k%2 == 1:
    B = []
    for j in range(k-1):
        B.append(A[j+1]-A[j])
    maxB = B.index(max(B))
    if B[maxB-1] + B[maxB] > B[maxB]+B[maxB+1]:
        A.remove(A[maxB])
    else:
        A.remove(A[maxB+1])
    k -=1
score = 0
for i in range(0,k,2):
    score += abs(A[i]-A[i+1])
print(score)
```

と、ここまで考えて時間切れになった。
後々考えると間違ってはないと気がするけど汎用性がない方針ですね。
$k = 1, 3$のときに成立しなくなったりするし。

公式解説だとKが奇数の場合は余らせる靴下を決めて全探索。それぞれの奇妙さの合計は累積和を使って求めるとある。この累積和は最初からと末尾からの両方を求めておいて、余らせるところで参照する累積和を切り替えればいい。
また、余らせる靴下はAのうち$A_1, A_3, A_5,…$に限られるはず（$A_2, A_4$…を余らせると$A_1, A_3, A_5,…$を余らせたときに比べて奇妙さが余計に生じる）。
```python:C'
n, k = map(int, input().split())
A = list(map(int, input().split()))
if k%2 == 1:
    sumh = [0]*(k+1)
    sumt = [0]*(k+1)
    for i in range(1, k):
        sumh[i] = sumh[i-1]
        if i%2 == 1:
            sumh[i] += A[i]-A[i-1]
    for i in range(k-1, -1, -1):
        sumt[i] = sumt[i+1]
        if i%2 == 1:
            sumt[i] += A[i+1]-A[i]
    ans = float('inf')
    for i in range(0, k+1, 2):
        ans = min(ans, sumh[i]+sumt[i])
    print(ans)
    exit()
else:
    score = 0
    for i in range(0,k,2):
        score += abs(A[i]-A[i+1])
    print(score)
```
もうちょっと効率良いやり方がある気もするが……

# D
D問題が簡単らしいのでやってみる。
```python:D
import bisect
n, q = map(int, input().split())
R = list(map(int, input().split()))
sortR = sorted(R)
sumR = [sortR[0]]
for i in range(1, len(R)):
    sumR.append(sumR[i-1]+sortR[i])

for _ in range(q):
    query = int(input())
    print(bisect.bisect_right(sumR,query))
```
本当に簡単だった。累積和取って二分探索するだけ。

B問題とC問題が難しい回だったみたいですね。本当にrateを上げたいなら解く問題の選び方も重要かも。
見守りカメラを家にあるもので実現する方法

# 背景・目的

+ 家にある動植物を見守る`見守りカメラ` 専用のIPカメラも色々ありますが、それを使わずに実現する方法をいくつか調査・試してみたので備忘します

+ 条件
    + PCで見ることができる
    + PCとは独立して無線で動画を飛ばすことができる
+ あるもの
    + Gopro Hero5
    + Sony カメラ
    + 使っていない iPhone 7
    + PC: MacBook Pro (15-inch, 2016)

# 方法

- [gopro wi-fi hack](https://github.com/KonradIT/goprowifihack)
- [Imaging Edge Webcam](https://support.d-imaging.sony.co.jp/app/webcam/ja/)
- [FaceTime](https://apps.apple.com/jp/app/facetime/id1110145091)
- [連係カメラ](https://support.apple.com/ja-jp/102546)

# GoPro wi-fi hack

GoProのカメラをWi-FiでPCと接続し、Webカメラ化する方法

通常のアプリを利用するのではなく、GoProの非公開APIを利用してGoProに写っている動画を見るという方法

```mermaid
graph TD
    subgraph 家
        対象物
        GoPro
        Mac
        自分
    end

    対象物 -- 3. 映像 --> GoPro

    GoPro <-- 1. wi-fi接続 --> Mac
    Mac -- 2. ストリームAPI指示 --> GoPro
    GoPro -- 4. UDP --> Mac
    Mac -- 5. 映像 by ffplay --> 自分
```

- [こちらのGitHubレポジトリ](https://github.com/KonradIT/GoProStream)のコードを使うと、上記を実現できる
- 前提条件
    - Macにffmpegがインストールされている
    - MacにPython or Rubyがインストールされている（上記のGitHubではpython, rubyのコードしかないが、リクエスト処理・ffplayの呼び出しができればどの言語でもできる）
- 仕組み
    - GoProとPCを接続すると、GoProのIPが`10.5.5.9`, PCのIPが`10.5.5.100`となる
    - PCから、`10.5.5.9`に対して、UDPで映像を送ってくれという指示を出す
        - `http://10.5.5.9/gp/gpControl/execute?p1=gpStream&a1=proto_v2&c1=restart`
        - その他のコマンドは、[goprowifihack](https://github.com/KonradIT/goprowifihack)にまとまっている
    - すると、`10.5.5.100:8554`でUDPで映像を受け取れるので、ffplayで映像を受信しMacで表示する
        - `ffplay -fflags nobuffer -f:v mpegts -probesize 8192 udp://10.5.5.100:8554`

- ポイント
    - Hero5 Sessionの場合、UDPで送れる最大の解像度が720p
        - ストリーム配信に対応している解像度は、撮影できる解像度と一致しているわけではなかった
    - 映像のみで、音声は受信できない
    - ストリームする画像に関する設定は限定的
    - ビデオモードにしないとストリーム配信されなさそうだった

# Imaging Edge Webcam

SonyのPCソフトをインストールし、カメラをWebカメラとして使う方法。
調べてみて、無線は難しそうだったので試していない。

```mermaid
graph TD
    subgraph 家
        対象物
        camera[Sonyカメラ]
        Mac
        自分
    end

    対象物 -- 3. 映像 --> camera
    camera <-- 1. 有線接続 --> Mac
    Mac -- 2. 映像出力指示 --> camera
    camera -- 4. 映像 --> Mac
    Mac -- 5. 映像 --> 自分
```

- ポイント
    - ソフトウェアをインストールすれば実現できる
    - こちらも、カメラで撮影できる解像度とストリームさせられる解像度は異なる模様
        - 人によっては、解像度を上げるためにHDMIをキャプチャボードで取り込んでPCで表示している人もいた
    - ストリームする画像をある程度前処理させられそう


# FaceTime

iPhoneに標準搭載されているFaceTimeというアプリを使う方法


```mermaid
graph TD
    Appleサーバー
    subgraph 家        
        対象物
        camera[iPhone]
        Mac
        自分
    end

    対象物 --> camera

    Appleサーバー --> Mac
    camera --> Appleサーバー
    Mac --> 自分
```

- 手順
    1. iPhoneでFaceTimeのリンクを発行し、AirDropでMacに送る
    2. MacでFaceTimeに参加する
    3. iPhoneでもFaceTimeに参加し、Macからの参加を許可する
- ポイント
    - 簡単に設定できる
    - 動画だけでなく音声も受信できる
    - 家のネットワークだけで完結できない
    - 暗いところでもいい感じに明るさを調整してくれる（画像の前処理が自動でかかる）

# 連携カメラ（Mac・iPhoneの標準機能）

今回、Macが古くて試せなかったが、今回のシステム要件が合わず試せなかった。
が、新しいiPhoneとMacを持っているなら、これが良さそうな気がする

- 要件
    - iPhone XR 以降 (2018 年以降に発売されたすべての iPhone モデル)
    - macOS Ventura 以降に対応したすべての Mac
- ポイント
    - ちゃんと調べていないからアレだが、Webカメラとして機能する
    - FaceTime, QuickTime PlayerでiPhoneのカメラを認識するようになる
    - 有線でも無線でもOK

# まとめ

今回あるもので色々調べてみましたが、結局FaceTimeが用途に合いそうだという結論になりました。
新しいMac欲しい・・
Firebase+chatGPT API+NEXT.jsをUdemyで学習したのでアウトプット＆おすすめしておきます

# はじめに
[【AIチャットアプリ開発】Next.js & Firebase & ChatGPT APIを使ったWebアプリ開発講座](https://www.udemy.com/share/109Dki3@QulR-kdU_Q35M8cpHUUi-GZi7Rtmw4n2iKDDIGNlyFcDMcbs7OJ540EvMqby3TglnA==/ "Udemy")

で学習したのでアウトプットとし、学びたい方向けに紹介しておきます。

記事では、学んだ内容と苦労したこと、追加で２つほど簡単な機能をつけたので紹介します（全然大したことないやつです）


<img width="600" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037238/b9352a98-cc19-9966-5262-f316b600e146.png">

<img width="400" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037238/b59ba47f-bb02-f937-9f15-8a25188afa44.png">


# 成果物
firebaseでデプロイした成果物です。
URL: https://chatapplication-with-cha-e3c90.web.app/

（openAIの料金上限つけてるので、上限分使うと使用できなくなりますので注意、、）

chat-GPTのクローンアプリで仕様は下記です。
- React-Hook-Form & firebase Authenticationを使ったログイン、新規登録
- 部屋を作ってチャットするとopenAI-APIにテキストが飛ぶ
- OpenAPIからレスポンスが返ってくる
- firestoreにテキストを保存
- firestoreからデータを取得し、画面にレンダリング
- firebase hostingで静的ファイルとしてデプロイ

ここまでが講座の内容で、
残り追加機能として、下記をやってみました。
- google認証を追加
- 送信ボタンを`Shift+Enter`で送信できるように
- レスポンシブ対応
- チャットを送った時に余計な機能を追加(ご自分で確かめてみてください)

google Authはいろんな方が記事にしており、その辺の記事と[公式ドキュメント](https://firebase.google.com/docs/auth/web/google-signin?hl=ja "firebase")を参考にすればできるかと思います。


# この講座で学べたこと
- firebaseの概要とどんなドキュメントを読めばわかるか理解できた
- NEXT.jsの基本がわかった　（ページの作り方や静的ファイルへのbuild方法など）
- ReactのUseContextの使い方がわかった
- Open AI APIの使い方、送信方法がわかった(すこしお金がかかる最初デポジットとして＄５とられる)

全て基本レベルで困ったらどんなふうに調べればいいかわかったのが大きいかなと。
（どうしても最初の導入はどのドキュメントのどこを見ればいいかわからないのが多いので。）


# 苦労したこと
最後のデプロイがうまくできず、１〜2日かかりました。。。
対応内容は別記事にしてあります。
https://qiita.com/kiyomasa05/items/f8e968b95dfd7a7a13e1

あとJSとfirestore serverTimestampを使った日にちの計算ができるようになりたいです。(うまくできず機能落としてしまった)

# こんな方におすすめ（おすすめの理由）
必要な前提　（前提はこれぐらいしか必要ないかと）
- Reactの知識はすこしある
useState,useEffectとかを知っていれば問題なさそうな気がします。
自分もなんだっけ？って再度調べながら学んだので、すぐにキャッチアップできると思います

こんなことが知りたい方向け
- NEXT.jsの概要を知っておきたい（あまり触ったことがない）
- firebase触ったことない、少し知っておきたい
- OpenAIのAPI触ってみたい
- 最近React触ってない、復習がてら何かアウトプットしたい



# おわりに
エンジニアの記事がchromeからレコメンドで色々くるのですが、firebaseやOpenAI APIなどよくわからず、使ってみたいなと思っていたのでこの講座で学べてよかったです。すこしは記事の内容がわかるようになりそう。


# 参考
https://firebase.google.com/docs/auth/web/google-signin?hl=ja

https://www.udemy.com/share/109Dki3@QulR-kdU_Q35M8cpHUUi-GZi7Rtmw4n2iKDDIGNlyFcDMcbs7OJ540EvMqby3TglnA==/
うるるに入っての3ヶ月を振り返ってみました！！！

この記事はうるる [Advent Calendar 2023](https://qiita.com/advent-calendar/2023/uluru)の25日目の記事です。

## はじめに
皆さんはじめまして！えんフォト事業部開発課でフロントエンドを担当している岡本と申します。

今回は入社して三ヶ月(エンジニア3年目)の私が
* 「入社のきっかけ🌸」
* 「入社してみてのギャップ💡」
* 「転職後の感想😁」

について、私自身の経験を交えつつ、率直な感想をシェアさせていただきます。振り返り記事となりますが、ぜひ最後までお付き合いください🙇‍♂️ 皆さん、メリークリスマス🎄🎅🎄🎅🎄

## 入社のきっかけ
前職では、某自動車会社の業務アプリ開発に携わっていました(その前はコックという異色の経歴です。。。)
開発自体はやりがいを感じるものでしたが、人生は短いもの。元々子供が大好きで興味を持っていたサービスである「えんフォト」の開発を志しました。また、カジュアル面談や面接を通して、このチームと一緒に働きたいと感じ、入社を決意しました。ご縁があり本当に良かったです😭


## 入社してみてのギャップ
入社前後でのギャップについてですが、正直な感想としては大きなギャップはありませんでした！想像していた以上に、理想通りの環境とチームであったことが振り返ってみて感じます。

ギャップがない理由としては
面接時にお互いをかなり深掘りできた事だと思っています。
私の例で言うとカジュアル面談を2回行っていただけて、開発メンバーとも沢山お話しすることができました。なので、自分の事はもちろん知ってもらえましたし会社の事も面談時に沢山聞くことができました。

また、入社後はフロントエンドの先輩との毎朝の1on1や、上司との週3回のフォロータイムは、技術的なことからプライベートな悩みまで率直に話せる環境を築いてくれました。めちゃくちゃ感謝しています🙌


## 転職後の感想

転職後の感想として三点上げさせていただきます。

 ### ①プロダクト愛
当たり前なのかもしれませんが、部署全体で「えんフォト」に対する愛を沢山感じました！オンボーディングの一環として、各課の課長にそれぞれの業務内容や理想の姿を丁寧に説明してくださったり、課の垣根を超えて飲み会に誘って頂いた時も、どうしたらもっといいサービスになるか雑談ベースではありますが、みんなが本気でサービスを伸ばしていきたい思いが伝わってきました！！

前職が受託系の会社であったため、プロダクトに対する情熱を持ちにくかった経験もあります。その点で、ここでは直接プロダクトに注ぎ込める環境に身を置けることが、大きな変化でした。

 ### ②成長サポート
個人の成長サポートが本当に素晴らしいです！！！

どうすればその人が一番成長できるのか、そしてどのようなキャリアを目指しているのか、日々納得して働けているのかという視点で本気で向き合ってくれます。

毎月の月次1on1では、個人の課題を共有し、解決策や悩みに対するフィードバックを丁寧にくれます。自分の成長を真剣にサポートしてくれる姿勢がめちゃくちゃ嬉しいです。

また、技術的な課題を相談した際には、フロントエンドコンサルタントの方と週2時間のフォローアップ時間を設けていただけました。こんなにも手厚いサポートを受けることができて、本当に感謝の気持ちでいっぱいです🙇‍♂️


 ### ③一緒に働くメンバー
仕事をする上でのチームメンバーとの関係性も、大きな魅力です！

皆それぞれのプロフェッショナルであり、技術力も非常に高く尊敬しているのですが、何よりも「優しさ」を感じます！入社後のフォローアップもそうですが、出社した時は気軽にランチに誘ってくれたりとそんな気遣いが嬉しかったです😀Slackのレスポンスがめちゃくちゃ早いのもありがたいです🙏

来年はメンバーとのコニュニケーションをもっと意識して、開発組織全体の一体感を高めていきたいと思っています(技術力もしっかりつけます笑)

## 最後に
この三ヶ月間、多くの方々からサポートをいただきました！！
心から感謝しています！今後も一層のご指導をよろしくお願いいたします！
また、フロントエンドの仲間を募集中ですので、一緒にサービスを盛り上げていきたい方！是非、カジュアル面談をお待ちしております🙇‍♂️🙇‍♂️🙇‍♂️
Proxmox8 を試してみる　その１５　VMでUSB機器を使用する

# Proxmox8 のVMでUSB機器を認識させたい
表題通りです。GPUパススルーを設定するよりこちらは簡単でした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/44540/4971f8c7-c5b3-c23c-e772-1b751a3a7feb.png)

# PX-W3U4 っていう機器を認識できるのだろうか？
興味本位で買った PX-W3U4 ですが、埃かぶっていたので出してきました。

https://komone-life.com/2021/03/07/how-to-install-epgstation-docker-bcas-3/

https://komone-life.com/2020/03/09/how-to-install-docker-in-ubuntu/

https://hplugr2.zapto.org/blog/chinachu_mirakurun/

# へええ
エンジニアでない人でも使うことが出来るツールT-DASH

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3660650/abd09f41-d30a-3bea-903c-0d4ffd482e22.png)

エンジニアでない人でも使うことが出来るツールとして、とても革命的だと思います。

実際に実際にT-DASHに申し込んで利用してみたのですが、エンジニアでない私でも簡単に作ることが出来たので、とてもよかったです。