OmniAICreator/Qiita-1.07M huggingface dataset:
Pretterでコードを綺麗に保つ！VSCodeでの設定方法

# Pretterを使ったコードを綺麗に保つ方法

コードの可読性を保つことは、開発者にとって重要なスキルです。そのためには、コードフォーマットを統一することが非常に効果的です。ここでは、Pretterを使ってコードを自動的に整形し、VSCode環境での設定方法を紹介します。

## Pretterとは？

Pretterは、コードフォーマットツールで、JavaScriptやTypeScript、HTML、CSS、JSONなど、さまざまな言語に対応しています。コードの整形を自動化し、チーム全体でコードのスタイルを統一することができます。

## VSCodeでPretterを使う方法

VSCodeでPretterを使うには、まずPretter拡張機能をインストールする必要があります。

1. VSCodeを開き、左側の拡張機能アイコンをクリックします。
2. 検索バーに「Prettier - Code formatter」と入力し、表示された拡張機能をインストールします。

インストールが完了したら、VSCodeでPretterが利用できるようになります。

## Pretterの設定

Pretterを使うためには、いくつかの設定を行う必要があります。以下に主な設定項目を紹介します。

### 1. デフォルトのコードフォーマットツールをPretterに設定

VSCodeの設定でPretterをデフォルトのコードフォーマットツールとして設定できます。

```json
{
  "editor.defaultFormatter": "esbenp.prettier-vscode"
}
```

### 2. ファイル保存時に自動でコードをフォーマット

コードを保存したときに自動で整形されるように設定できます。

```json
{
  "editor.formatOnSave": true
}
```

これで、ファイルを保存するたびにPretterが自動的にコードを整形します。

### 3. Pretterの設定ファイルを使う

さらに詳細な設定を行いたい場合は、プロジェクトルートに`.prettierrc`という設定ファイルを作成できます。これにより、チーム全員が同じフォーマット設定を共有できます。

例えば、次のように設定することができます。

```json
{
  "singleQuote": true,
  "semi": false,
  "trailingComma": "all"
}
```

## Pretterを使うメリット

Pretterを使用することで、以下のようなメリットがあります。

- **一貫性**：チーム全体で同じコードスタイルを維持できます。
- **時間の節約**：手動でコードの整形を行う必要がなくなります。
- **エラーの削減**：フォーマットミスによるエラーを防げます。

## まとめ

Pretterは、コードの整形を自動化し、開発者が可読性の高いコードを書く手助けをしてくれます。VSCodeでの簡単な設定だけで、すぐに使い始めることができ、チームでの開発にも役立ちます。ぜひ、Pretterを使ってコードを綺麗に保ちましょう！
GitHub、はじめてみました (Part 2)

Gitを使っている中で備忘録としてまとめたくなったTipsたちを書いていきます！

# No.0001
**Mainの変更を各ブランチに反映**
```bash:bash
git pull origin main
git checkout <ブランチ名>
git merge main
git push origin <ブランチ名>
```

# No.0002
**ローカルで作成したブランチをリモートに反映**
```bash:bash
git push -u origin <ブランチ名>
git branch -r
```
-u: ローカルブランチとリモートブランチを追跡するために設定
-r: リモートを確認

# No.0003
**ローカルでブランチを削除してリモートに反映**
```bash:bash
git push origin -d origin/<ブランチ名>
git fetch --prune
git branch -r
```
--prune: リモート追跡ブランチ（ローカルに残るリモート参照）を削除

# No.0004
**間違ってステージング＆コミットしてしまった場合の救世主**
```bash:bash
git reset --soft HEAD~1 # コミットのキャンセル
git reset # ステージングのキャンセル
```
上記の順番（コミットをキャンセルしてからステージングのキャンセル）が重要です！

# No.0005
**リモートで更新した内容とローカル更新内容が異なるのでpull/pushできない :(
```bash:bash
git stash # ローカルの変更を一時避難
git pull
git stash pop # 一時避難していた内容を反映
```
このあとは通常通りaddでステージングしてcommitからのpush！

# No.0006
**ローカルには残したままリモートの不要なフォルダを削除したい！
```bash:bash
git rm -r --cached <folder1> <folder2>
```
このあとは通常通りaddでステージングしてcommitからのpush！

# No.0007
**git statusも使えない？？？
```bash:bash
git status
> fatal: .git/index: index file smaller than expected
rm -f .git/index
git reset
```
これで元通り

:::note info
**皆さんの経験談やTipsもぜひコメントください！**
:::
【Minecraft】プラグインサーバを運用する上で便利なダウンロードスクリプト

[Paper](https://papermc.io/)に[Geyser](https://geysermc.org/download?project=geyser)と[Floodgate](https://geysermc.org/download?project=floodgate)を導入してクロスプラットフォーム対応をしている。サーバ本体とプラグインを更新するときに用いているスクリプトを紹介する。curlを使用している。

# Paper
Paperはダウンロードリンクをそのままwgetしても手に入るのだが、[公式が案内している方法](https://docs.papermc.io/misc/downloads-api)はそうではなかった。公式のものを少しアレンジしている。curl以外にjqを用いるので必要に応じてインストールされたい。
```bash:download.sh
#!/bin/bash

PROJECT="paper"
MINECRAFT_VERSION="1.21.3"

LATEST_BUILD=$(curl -s https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds | \
    jq -r '.builds | map(select(.channel == "default") | .build) | .[-1]')

if [ "$LATEST_BUILD" != "null" ]; then
    JAR_NAME=${PROJECT}-${MINECRAFT_VERSION}-${LATEST_BUILD}.jar
    PAPERMC_URL="https://api.papermc.io/v2/projects/${PROJECT}/versions/${MINECRAFT_VERSION}/builds/${LATEST_BUILD}/downloads/${JAR_NAME}"

    # Download the latest Paper version
    echo "Latest stable build is $JAR_NAME"
    curl -o paper.jar $PAPERMC_URL
    echo "Download completed"
    chmod 744 paper.jar
else
    echo "No stable build for version $MINECRAFT_VERSION found :("
fi

exit 0
```
ダウンロード後にパーミッションを変更するようにしている。

# GeyserとFloodgate
[公式のダウンロードAPIの説明](https://geysermc.org/wiki/api/downloads.geysermc.org/download-specific)を基に構成した。
```bash:download.sh
#!/bin/bash

curl -L https://download.geysermc.org/v2/projects/geyser/versions/latest/builds/latest/downloads/spigot -H "Accept: application/json" --output Geyser-Spigot.jar
curl -L https://download.geysermc.org/v2/projects/floodgate/versions/latest/builds/latest/downloads/spigot -H "Accept: application/json" --output floodgate-spigot.jar

echo "Download completed"

chmod 744 Geyser-Spigot.jar
chmod 744 floodgate-spigot.jar

exit 0
```
こちらもダウンロード後にパーミッションを変更するようにしている
便利なWindowsのショートカット

# 初めに
皆さんは日頃からパソコンを利用されているでしょうか？
私はパソコンを利用する際にWindowsキーはどのような機能があるのだろうと思いました。
ただWindowsキーを押すだけだと画面左下にあるスタートが展開されるだけなので今まではこれだけしか機能がないものだと思っていましたが、いざ機能を調べてみると意外にも多くの機能があると判明しました。
# どんな機能があるの？
例えばWindows キー  + Ctrl + D で仮想デスクトップを追加することができたり、Windows キー  +  Ctrl +矢印キーで先程作成した仮想デスクトップから元の仮想デスクトップへ行き来することができます。![desuku.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3949580/f5e41319-55de-23bd-2825-3b57c01dcb0a.png)
Windows キー  +　tabキーでタスクビューを開き今まで開いた仮想デスクトップやウィンドウを見ることができます。
![スクリーンショット 2024-12-09 213719.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3949580/d134f40a-e0c5-5f18-5c1e-b001c6394f7c.png)

他にも様々な機能がありますが今回は覚えておくと便利かもしれないものを紹介していきます。
Windows キー  + Dでデスクトップの表示と非表示を切り替えます。急いでデスクトップ画面に戻りたい時などに使用するとよいでしょう。似た機能としてWindows キー  +  コンマキーがありますこちらはWindows キーを押している間だけデスクトップ画面を表示するショートカットとなっています。
![スクリーンショット 2024-12-09 212852.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3949580/fe873828-0efc-b508-7131-ef9e3b36fa11.png)

Windows キー  +Ｌで画面をロックすることができます。少し席を離れる時や画面を見られてくない時などに使用すると良いでしょう。
次にWindows キー  +IでWindowsの設定画面を開くことができます。インターネットの設定やデスクトップ画面の背景を変更したい時などに利用しましょう。
最後に紹介するショートカットはWindows キー＋1～0キーでタスクバーに表示された番号と対応するアプリケーションを起動することができます。この機能を使えば普段よく使用するアプリケーションをマウスを使わなくても起動することができるのはかなり便利ですね。
上の画像を参考にしてみるとWindows キー＋６でyoutubeを開くことができます。
# 終わりに
今回紹介した機能の他にも多くのショートカットがあります。ショートカットを覚えると今までマウスを使用してやっていた作業もキーボードのみで行えるようになります。こうすると作業効率を上げることができると考えられます。以上で記事を終わります最後まで読んでいただきありがとうございました！
【おすすめ製品】Macbookから3台のモニターに出力したかった

## 対象者
- 家やオフィスでMacbookを3台のモニターに繋げて作業したい方
- 新しいMacbook（やモニター）の購入を検討されている方

## なぜこの記事を書くのか
Macbookから3台のモニターに出力したかっただけなのに…
2万円近い損失を出してしまいました。

同じような失敗をする人が出ないよう、供養として記事を書かせていただきます。
（結構Macbook→トリプルモニターの情報少ない気がしているので）
少しでもお役に立てれば幸いです。

## 結論
大きく分けると以下の2択になると思います。

### パフォーマンス / ロマン重視の方 (自分はこっちでした)
①**性能の高いMacbookを買う** つまり、Macbook Pro M2 Max or M3 Max or M4 Max ([Apple公式サポートページ参照](https://support.apple.com/ja-jp/101571)) を買う
②**1本ずつ繋ぐ** または デイジーチェーン対応モニターを買ってデイジーチェーンする

自分はデイジーチェーン未検証(非対応モニタを先に買ってしまいました)ですが、
あまり期待はしない方がいいかもしれないです。
(繋げば繋ぐほどパフォーマンス落ちるみたいなので)

#### メリット
- リフレッシュレートが高い、ぬるぬる動く
- そのほかMacの性能が高い、マットブラックかっこいい

#### デメリット
- **価格が高い**（Pro M3 maxを買ったのですが中古でも40万円しました…）
- 接続が若干面倒（Macを持ち出す機会が多い人は大変かも、慣れればそこまででもない）

### 毎回の接続の楽さ / コスパ重視の方
①**ほどほどの性能なMacbookを買う** 
②**ドッキングステーションを買う**
自分が方もの
[【ビジネス応援セール】ドッキングステーション HDMI3つ トリプルディスプレイ 4K 3画面 10in1 Win mac対応 400-VGA023](https://direct.sanwa.co.jp/ItemPage/400-VGA023?gclid=Cj0KCQiAx9q6BhCDARIsACwUxu77xY28b2VXvlSWBRv5bV0Ca8g5ouinBQsqeKUThHRiLy4hUFmTizMaAuo9EALw_wcB&ef_id=Cj0KCQiAx9q6BhCDARIsACwUxu77xY28b2VXvlSWBRv5bV0Ca8g5ouinBQsqeKUThHRiLy4hUFmTizMaAuo9EALw_wcB:G:s&gad_source=1)
なんと本来3画面出力非対応のM1,M2のMacも3画面出力できるようになるという優れモノです。

#### メリット
- 安い
- 毎回の接続が楽になる
- 他にも一括で色々接続しておける（優先LANやAUDIOの端子、その他USBなど色々）

#### デメリット
- (**M3 maxに比べると**)リフレッシュレートが低い。1,2画面目は60Hzだが3画面目は30Hzになる＆デスクトップ切り替えでカクツク
- 自分が買ったドッキングステーションを通すとプライムビデオを見ることができなくなるらしい。画面収録をしている判定になるっぽい

## お分かりいただけだだろうか
つまり私は3画面に移すことのできるMacbookであるM3 maxのMacbook Proを買って性能に驚愕したあと、毎回3本の線を繋ぐのが面倒だと思いこのドッキングステーションを介してモニターに接続して、リフレッシュレートの低下にガックリしてしまったのである。

勘違いしないでいただきたいのは、このドッキングステーションは素晴らしい商品であるということです。
なんといっても半分以下の値段のMacbookに繋げるだけで本来できない3画面出力ができるようになってしまうのですから…。
ちょっとお高いですがそれだけの価値はあると思います。
ただ、ケーブル挿す手間を省くためだけに、リフレッシュレートを下げてまで買うべきものかというと違うなって感じです。

まだ皆さんは遅くないはずです。
(私が過去に戻れるとしてもだいぶ悩む2つの選択肢だとは思いますが)ぜひよくご検討ください。
1つだけ加えておくと、**1度、M3maxのぬるぬる具合を体感してしまうと元に戻るのは個人的には難しい気がします**

私この経験がどなたかのお役に立てると幸いです。

## (おまけ)個人的反省
### 高い買い物はレンタルしてみたり、家電量販店で直接みたりする
ただでっかい家電量販店さん2軒回ったんですけどの人もまともに答えてくれる方いらっしゃらなかったんですよね…
調べても先駆者はなかなか見つからないし厳しい戦いでした。

### ゴールから逆算して、安く済む手段から試す
3画面出力だったら正直Airのままでもドッキングステーションにさえ課金すれば実現できたはずなので。その後
まあPro買えてよかったとは思っていますが…！ぬるぬるだしメモリが足りないということは全然ないです。めちゃ快適です。
Python/クラスオブジェクトより値を取得する

クラスメソッドの書き方を理解するのに苦労したので備忘録



```python

# -*- coding: utf-8 -*-
class Test:
    def __init__(self, test_id=None, name=None, age=None):
        self.test_id = test_id
        self.name = name
        self.age = age

    @classmethod
    def test_obj(cls, param):
        return cls(
            test_id=param.get('test_id'),
            name=param.get('name'),
            age=param.get('age')
        )

class TestAdd:
    def add(self):
        param = {
            'test_id': 1,
            'name': 'mike',
            'age': 10
        }
        result = Test.test_obj(param)
        return result

class TestResult:
    def display(self):
        test_add = TestAdd()
        result = test_add.add()
        print("Test ID: {}, Name: {}, Age: {}".format(result.test_id, result.name, result.age))

# 実行部分
if __name__ == "__main__":
    test_result = TestResult()
    test_result.display()


```
キーワード「E」を監視せよ！

## ログあるある
いつの時代でもシステムの動作確認では重要な役割をする「**ログ**」ですが、
「Error」ひとつでも表現方法はアプリ/ミドルによって様々です。

例えば以下のようなエラーログがあります。

**1. ど直球**
```
PROCESS | Error | Host unknown.
```
**2. コロン系**
```
E:Host unknown 
```
**3. カッコ系**
```
[E] Host unknown 
```
**4. 察して系**
```
E Host unknown 
```

## さて、どう監視しようか？
オールドツール(と言っては失礼かも）では、特殊文字を気にしないものもあり、
まんまの形でログ監視キーワードに指定していました。

```
文字列にキーワード[E]があったら、アラート検知・通知や！
```
```
文字列にキーワードE:があったら、アラート検知・通知や！
```

## Datadogでは？
「Error」はそのままのキーワードでも検知出来ます(本当は良くない)が、
特殊文字を含むとそのまま文字としては使えません。
そこで、2通りのやり方を考えました。

### 其の１ DatadogAgentでGrepしちゃおうぜ！
DatadogAgentがインストールされている前提ですが、
ログ監視のconf.yamlに以下のように設定しました。

```
  - type: file
    path: /var/log/test.log
    service: hogehoge
    source: hoge-channel
    log_processing_rules:
     - type: include_at_match
       name: inc_messages_err
       pattern: (E:)
```

さて、テストしようか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/322ce25d-94e0-9256-3a4a-5958943df2cf.png)

結果は、、うむうむ。よしよし。「E:」だけを取得出来たぞい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/19fea41e-d08d-abab-1bc0-f8ccbcf473d9.png)

でも、「E:」以外のログが取得出来ないじゃん！！
障害対応等では前後のログが意味を持ち、文脈が重要な場合もあるので没。。

### 其の２ Datadogコンソール上で特殊文字をエスケープすれば良くない？

DatadogAgentではログの絞り込みはせず、全量を連携させます。
連携されたログの中から、「E:」を探す作戦です。

こんな感じでどうかな？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/f414f55e-3d3f-1c1e-11fd-113abcaf54dc.png)
だめだ （T T）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/bd367875-c8b2-a417-d922-5d088509434d.png)

## じゃあ、ぐろっくぱーさーを使おう(Grok Parser）

Datadogには協力な**Pipelines**があるじゃないか！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/aba9dd1b-3636-1629-3a36-21eb93c6d5e0.png)
「https://docs.datadoghq.com/ja/logs/log_configuration/parsing/」より引用

パイプライを新規で作成→今回はベタに「E-colon」と命名
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/1b9e5e74-0ffe-36e1-3dd9-91aea10e4fea.png)

ログのサンプルと定義を作成すると簡単にルールが出来ちゃう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/1626bed3-0f0e-1880-e382-267c67c8e691.png)

後は、作成したルールをログエクスプローラーで検索してみると、、、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/bcb4e72f-da57-7efe-c06d-8ec17f192416.png)

出来た！これで他のログを取得しつつ、監視用のキーワードも設定出来るぞぉぉぉ
どんなパターンでも特殊文字でもきっと大丈夫だ！たぶん！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/409879/e7a722f3-1639-d1cd-c2eb-2e433db76b63.png)

## という事で、ログ監視はまだまだ続く

今回はとてもシンプルなものの話でしたが、ログが複雑なパターン等も出てきており、
色々と試行錯誤をしながら対応をしている日々です。
今後はパターン分析等での活用など、まだ(自分が)知らないDatadogの機能と格闘する所存です！

おしまい
ミュータブル，イミュータブルな変数とは(Python)

## ミュータブル，イミュータブルとは
ミュータブル，イミュータブルは変数の型に対して使用する言葉で，Pythonの変数はミュータブルな型とイミュータブルな型に大別することができます．

・ミュータブルな型:　リスト，辞書
・イミュータブルな型:　int, float, 文字列, bool, タプル

イミュータブルな型の変数(以下イミュータブル)が普通の変数であり，いつもやっているように代入ができる変数のことです．
ミュータブルな型の変数(以下ミュータブル)もいつも普通に代入をしていると思っていても，実際の挙動は異なります．

イミュータブルは変数に新しく値を代入してら，更新されると共にメモリ内の変数があった位置(アドレス)も変更されます．しかし，ミュータブルな変数は新しく変数を代入し直してもアドレスが変更されません．
そのため，以下のようになります．

```python
x = [1, 2, 3]
y = x
y.append(4)
print(x)
print(y)
```
出力
```
[1, 2, 3, 4]
[1, 2, 3, 4]
```

編集した変数はyのみですが，xの値も変更されてしまっています．これは，**xもyもアドレスが同じため，同じ変数という扱いになるためです．**
(ここではシャローコピー，ディープコピーの説明は省きます．気になる人は調べてみてください．)

そのため，以下のコードのように書きます．
```python
x = [1, 2, 3]
y = x.copy()
y.append(4)
print(x)
print(y)
```
出力
```
[1, 2, 3]
[1, 2, 3, 4]
```
こうすることにより，xとyは別アドレスの別の変数になります．
また，ミュータブルな型の変数にミュータブルな型の要素がある多次元リストのような型の場合は上記のようにしても最終的な要素のアドレスが共通してしまうため，以下のようにします．
```python
import copy

x = [[1, 2], [3, 4], [5, 6]]
y = copy.deepcopy(x)
```

## 関数の引数にミュータブルな型をいれる場合
上記のことから，関数の引数にミュータブルを指定しまうと，関数内でミュータブルを編集してしまっただけで引数元の内容も変わってしまいます．
そのため，通常引数にミュータブルを指定する場合は以下のようにしましょう．
```python
def hoge(list_array):
 list_array = list_array.copy()
 list_array.append(4)
 return list_array
```
このcopyする処理が大切です．
くそみたいなエンジニアからの脱却

## Udemyでの自己啓発

### コース
【世界で70万人が受講】Web Developer Bootcamp 2023（日本語版）

### 選定理由
いくつかのYoutuberがおすすめしてたから
※だけど、全員プロモーションついてた…

#### Tips
Udemyで受講したい場合、セールありきの金額設定になっているらしいので
その期間でちゃんと買う必要がある
ちなみに、今回のコースは、92% OFFで、2200円

#### 意気込み
とりあえず、みてノウハウをQiitaに残していく予定
【Advent Calendar 2024 #9日目】AWS Certified AI Practitioner受験メモ

# はじめに
本記事は、「初めての一人アドベンドカレンダー2024 by hohe」の9日目の記事となります。
Advent Calendar 期間中は、AWSの生成AI/ML関連を中心に記事を投稿していきます。
9日目は目標の１つとしていたAWS Certified AI Practitionerを受験しましたので受験記録をまとめます。

# AWS Certified AI Practitionerとは
人工知能(AI)、機械学習(ML)、生成AIの概念とユースケースに関する需要の高い知識を実証する試験です
- 試験時間：90分
- 問題数：65問（うち採点対象は50問）
- 合格スコア：700点以上
- 2024年2月15日までにこの認定資格を取得することで、通常の認定バッジに加えてEarly Adopterのデジタルバッジも取得することができる

https://aws.amazon.com/jp/certification/certified-ai-practitioner/

# 試験勉強について
### 受験前の状態
AWSの認定資格としては以下を取得済み
- AWS Certified SysOps Administrator - Associate
- AWS Certified Developer - Associate
- AWS Certified Solutions Architect - Associate
- AWS Certified Data Engineer - Associate
- AWS Certified Solutions Architect - Professional
- AWS Certified Security - Specialty

機械学習の知識については、LSTMやRNN、Attentionの知識や機械学習を行った経験はあるが、AWSサービスは触ったことはない

### 勉強期間
約１ヶ月（平日1時間、休日・祝日2時間程度）

### 試験に使用した教材
勉強方法としては、主に問題集を進め、不明点を講座やBlackbeltの資料を見ながら埋めていく形で学習を進めました。特にAWSから提供されているサービス別資料は全体像やサービス間の関係性などを図として示してくれているので、理解が捗りました。

- Udemy

https://www.udemy.com/course/aws-ai-practitioner-certified/?srsltid=AfmBOoqEUAtAIFUDRJTu9RR8917lTCHsr9tsSo58kBjowOr7J2iJ8BK7&couponCode=24T3MT120924

https://www.udemy.com/course/practice-exams-aws-certified-ai-practitioner/?couponCode=24T3MT120924

- AWSサービス別資料

https://aws.amazon.com/jp/events/aws-event-resource/archive/?cards.sort-by=item.additionalFields.SortDate&cards.sort-order=desc&awsf.tech-category=*all

- AWS Skill Builder

https://explore.skillbuilder.aws/learn

### 受験結果と受けた感想
結果としては、無事合格することができ、早期特典であるEarly Adopterのデジタルバッジも取得することができました。試験自体はそれほど難易度は高くない印象を受けましたが、試験の性質上において機械学習の知識、特にAmazon SageMaker周りはサービスごとにできることをしっかり把握しておく必要があり、これまでAWS試験を受験されてきた場合でもしっかりAI/MLサービス周りを学習しておくことが必要だと感じました。

# おわりに
今回はAWS Certified AI Practitionerについての受験結果をメモとしてまとめました。無事合格できてホッとしましたが、先週にはre:Inventがあり、新しい生成AIモデルも発表されていたので、今後も知識のアップデートを行いながら、次はAWS Certified Machine Learning Engineer - Associate取得に向けて再度学習を進めていこうと思います。
LaravelでBearer認証とBasic認証を両立させる方法

とある日、Bearer認証を使っているシステムを、Basic認証がかかっている開発環境に設置する事になりました。

このような場合どちらの認証もAuthorizationヘッダを利用しているので、競合してうまく認証する事が出来なくなります。

すでに本番稼働しているシステムなのでBearerのヘッダ名を根本から変える事はしたくないので、AuthorizationヘッダでのBearer認証も残しつつ、この環境だけ別のヘッダ名にしようと思います。

Laravelでは``` $request->bearerToken() ```でBearerトークンを取得する事ができます。

これは、```Illuminate\Http\Concerns``` の ```trait InteractsWithInput``` にあります。

なので、ここにちょこっと細工をしてしまえば…。
```php
    public function bearerToken()
    {
        $header = $this->header('X-Authorization', null) ?? $this->header('Authorization', '');
        if (Str::startsWith($header, 'Bearer ')) {
            return Str::substr($header, 7);
        }
    }
```

通常の環境ではAuthorizationヘッダでBearerトークンが送られてくるのでそちらを取得し、
X-Authorizationヘッダが送られてくる環境ではそちらからBearerトークンを取得します。

あとは書き換えたファイルを/venderディレクトリとは違うどこか適当な場所に保存して、composer.jsonのfilesで修正後のファイルを読み込むように、exclude-from-classmapで元ファイルを読み込まないように指定してあげればokです。
PyCharmのHuggingFace連携機能について

この投稿はKDDIテクノロジーアドベントカレンダーの12/9分の記事となります。
[PyCharm2024.3からHuggingFaceとの連携機能が追加された](https://www.jetbrains.com/help/pycharm/hugging-face.html)のですが日本語の記事があまり無かったため試しに触ってみました。
※本機能はPyCharm Professional限定機能のようでCommunityEditionを利用されている方は利用不可となります。
ご注意ください。

HuggingFace連携機能は大きく分けて３つあるようです。

## Use Hugging Face models﻿
Webブラウザを開くことなくHugging Face Hub上に公開されているモデルのサンプルコードをインポート可能です。

使い方は簡単です。
①Pythonエディタ上から右クリックすると「HTモデルの挿入」という項目が追加されているので押下してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704655/9fb34964-1ee6-b14c-dcc3-f9b497c55cb5.png)

②Hugging Face Hub上に公開されているモデルが表示されるためインポートしたいモデルを選択してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704655/4cccb50d-93f7-bb07-353f-eddcb389199c.png)

③出来ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704655/7bb247df-67a4-fd23-0fa9-c47bf7032abd.png)

ただし、サンプルコードが貼り付けられるだけなのでパラメータチューニングやタスクの選択などが出来なかったためWebブラウザからコピペしたほうが今のところは良いかもしれません。
※画像のモデルのサンプルコードだと「text-generation」しか無いようでした。

## View model and dataset cards﻿
Webブラウザを開くことなくHugging Face Hub上に公開されているモデルのドキュメントを確認できる機能です。

具体的には以下画像の赤枠の部分にカーソルを合わせるとポップアップが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704655/581c32b2-7715-28a8-dc69-70f6a2c5963d.png)

エディタとWebブラウザを行ったり来たりすることが無くなるので個人的には実用的だと感じました。

## Hugging Face tool window
Transformersを使うと一度ダウンロードしたモデルはローカルキャッシュに保存されますが、
ローカルキャッシュ上に保存されたモデルをPyCharm上から管理する機能です。

左下辺りにHuggingFaceのロゴが出来ているので押下すると下記画像のようなウィンドウが開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704655/2cad3d98-7362-7bd9-469f-998c73822740.png)

各モデルを右クリックすると
・キャッシュから削除
・パスをクリップボードにコピー
することが可能です。

以上、３つの機能について是非皆様も活用してみてください。
ESP32と傾斜センサーで作る書類提出検知システム

## はじめに

「ポストに書類が入っているか確認する」という単純だけど手間のかかる作業を課題と捉え、この課題を解決するため、ESP32マイコンと傾斜センサを使用した自動検知システムを開発しました。定期的な確認作業を自動化することで、業務効率の改善を目指しました。

## システム概要

### 使用機材
- ESP32開発ボード
  - WiFi機能内蔵で、インターネット接続が容易
  - 安定した動作と豊富なライブラリが利用可能
  - 低消費電力で24時間稼働に適している
- SW-520D 傾斜センサーモジュール
  - Arduino用に最適化された安定性の高いモジュール
  - クリーンな信号出力が特徴
  - 傾斜角度に応じてON/OFF切り替えが可能
  - メンテナンスフリーで長期運用に適している
- ブレッドボードとジャンパーワイヤ
  - 必要に応じて配置変更が容易

### 動作の仕組み
1. 書類提出ポストのフタに傾斜センサーを設置
   - トレイのフタに傾斜センサを配置
   - 書類を投函したときに傾斜が発生する位置に設置
2. 書類が投函されると傾斜を検知
   - センサが傾斜を電気信号として検出
   - デジタル信号としてESP32に入力
3. WiFi経由でSlackに通知
   - 設定されたSlack WebhookにHTTPリクエストを送信
   - カスタマイズ可能なメッセージフォーマット

## 実装のポイント
まずリポジトリです。

https://github.com/keigo1110/box_to_slack

### 1. 安定性を重視した設計

誤検知や不要な通知を防ぐため、複数の安定化機能を実装しています。

```cpp
const unsigned long DEBOUNCE_DELAY = 500;    // チャタリング防止
const unsigned long NOTIFICATION_INTERVAL = 20000; // 通知の重複防止
const int NUM_READINGS = 10;                 // 平均化処理のサンプル数
```

#### デバウンス処理（チャタリング防止）
センサの物理的な揺れによる誤検知を防ぐため、500ミリ秒のデバウンス時間を設定しています。これにより、一時的な振動やノイズによる誤検知を効果的に防止できます。

#### 平均化フィルタ（ノイズ除去）
10回のサンプリング結果の平均値を使用することで、電気的なノイズや一時的な外乱の影響を軽減しています。この処理により、より安定した検知が可能になっています。

#### 通知インターバル制御（重複防止）
20秒間の通知抑制期間を設けることで、短時間での重複通知を防止しています。これにより、システムの使用者に適切なタイミングで必要な通知のみが届くようになっています。

### 2. エラー耐性の確保

長期運用を見据えて、様々なエラー状況に対応できる仕組みを実装しています。

```cpp
void handleSystemError() {
  errorCount++;
  if (errorCount >= ERROR_LIMIT) {
    sendSlackMessage("🔄 エラー回数が上限を超えたため再起動します");
    ESP.restart();
  }
}
```

#### WiFi接続の自動リトライ
ネットワーク接続が切断された場合、自動的に再接続を試みます。一時的な通信障害からの自動復旧が可能です。

#### エラー発生時の自動再起動
継続的なエラーが発生した場合、システムを自動的に再起動することで、fresh状態からの復帰を試みます。

#### システム状態の監視と通知
エラーの発生状況をSlackに通知することで、管理者が必要に応じて適切な対応を取ることができます。

### 3. シンプルな通知

ユーザビリティを重視し、シンプルで分かりやすい通知設計を採用しています。

書類が提出されると、Slackに「📄 書類が提出されました！」という通知が送られます。必要最小限の情報を、必要なタイミングで提供することにこだわりました。

- 絵文字を使用することで視認性を向上
- 簡潔な文言で状況を即座に理解可能
- 必要に応じてカスタマイズ可能な設計

## コード構成

- `run.ino`: 実際の運用プログラム
  - システム全体の制御ロジック
  - センサー読み取りとSlack通知の統合
  - エラー処理とシステム監視機能
- `notify_slack.ino`: Slack通知機能のテスト用
  - Slack Web APIの確認
  - メッセージフォーマットのテスト
- `tilt.ino`: 傾斜センサーの基本テスト
  - センサーの動作確認
  - 基本的なセンサー値の読み取り
- `tilt_re.ino`: リファクタリング済みセンサープログラム
  - 最適化されたセンサー制御
  - ノイズ対策の実装

## まとめ

シンプルな課題に対して、必要十分な機能を実装することで、安定して動作する実用的なシステムを構築することができました。

### 実装のポイント
1. 必要な機能に絞ったシンプルな設計
   - 過剰な機能を排除し、メンテナンス性を向上
   - 動作の安定性を最優先した設計判断
2. 安定性を重視したエラー処理
   - 予期せぬ状況への対応
   - 自動復旧機能の実装
3. 使いやすい通知形式
   - 最小限の情報提供
   - 直感的な理解が可能

「書類が届いているか確認する」という日常の小さな手間を、テクノロジーで解決できた良い例となりました。シンプルながらも実用的なこのシステムは、私たちの業務効率化の一助となっています。
Gemini APIを使って漢字をひらがなに変換する

# 概要

前回、Go言語の勉強のため「ぱ行で会話するための変換プログラムを作成」しました。（下記参照）

https://qiita.com/ishi720/items/3e747fbbc569494ce9d2

しかし「漢字をひらがなに変換する処理」が未実装だったので、Googleが開発した生成型人工知能チャットボットの**Gemini**のAPIを利用して実装していきたいと思います。

# 準備

- 下記URLからGemini APIのAPIキーを取得してください

https://ai.google.dev/gemini-api/docs?hl=ja

- GCPでGemini APIが有効になっているか確認してください


# プログラムコード

それでは、今回書いたプログラムです。
意外とコード量は少なく済みました。

```go
package main

import (
	"context"
	"fmt"

	"github.com/google/generative-ai-go/genai"
	"google.golang.org/api/option"
)

func main() {
	ctx := context.Background()
	text := "お寿司を食べる"

	// Gemini APIクライアントを作成する
	client, err := genai.NewClient(ctx, option.WithAPIKey("{YOUR API KEY}")) // 取得したAPIキーを指定
	if err != nil {
		fmt.Println("Geminiクライアントの作成に失敗しました")
	}
	defer client.Close()

	// モデルとプロンプトの準備
	model := client.GenerativeModel("gemini-1.5-flash") // Geminiのモデルを指定
	prompt := genai.Text("以下の漢字の部分をひらがなに変換してください: " + text)
	res, err := model.GenerateContent(ctx, prompt)
	if err != nil {
		fmt.Println("Gemini APIの呼び出しに失敗しました")
	}
	// 変換結果を出力
	fmt.Println(res.Candidates[0].Content.Parts[0])
}
```

ちなみに`以下の漢字の部分をひらがなに変換してください`の部分を変えてあげるだけで違うプログラムになります。なんか不思議な感覚です。


# 結果

そして変換結果です。なかなか精度が高いのではないでしょうか。

|変換前|変換後|
|--|--|
|お寿司を食べる|おすしをたべる|
|以心伝心|いしんでんしん|
|東京特許許可局|とうきょうとっきょきょかきょく|
|会議の最中に最中を食べたい|かいぎのさいちゅうに<font color="red">**さいちゅう**</font>をたべたい|
|祇園精舎の鐘の声、諸行無常の響きあり。娑羅双樹の花の色、盛者必衰の理をあらはす。|ぎおんしょうじゃのかねのこえ、しょぎょうむじょうのひびきあり。さらそうじゅのはなのいろ、じょうしゃひっすいの<font color="red">**り**</font>をあらわす。|

# 終わりに

今回は、**Go言語**と**Gemini API**を使って**ひらがな変換機能**を作りました。
精度は100％ではありませんが、質問の仕方を変えたり、変換後の文章をどのように使うかでカバーできそうです。

今度は[前回の記事](https://qiita.com/ishi720/items/3e747fbbc569494ce9d2)とプログラムと合体させて1つのアプリケーションを作成したいと思います。

以上、ここまで読んでいただきありがとうございました。
Tauriとvueでリマインドアプリを作ってみた[1]: 環境構築

## きっかけ
普段使っているアプリの中で、gitifyというアプリがあります。
GitHubの通知をMac上で出してくれるアプリです。（WindowsとLinuxでも使えそうですね）

https://gitify.io/

画面上のメニューバーにアイコンが常駐していて、クリックすると通知の画面が出る、よくある仕組みです。

![Screenshot 2024-12-09 at 21.03.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754242/7548827a-b505-51e8-08a1-1c54e8dafd6a.png)

通知が来たら緑色に変わっていて気づきやすくもなります。

![Screenshot 2024-12-09 at 21.03.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3754242/3fe4a47c-d7de-f599-5a77-7c3af8a1df5d.png)

## デスクトップアプリを作りたい
こう書くとただGitifyが好きな人の記事ですね。

お気づきかと思いますが、私は今回Gitifyのような通知アプリを作ってみたいと思いました。
GitHubだけでなく、自分でリマインドかけたいものがカスタマイズできて、チーム開発での当番の確認などを行いたい。それが目標となります。

### どうやって？
私はVueとRailsを主に使っている開発者ですが、デスクトップアプリについては少しだけelectronを使ったことがあるくらいでした。

そのため、electronを試してみたのですが、viteのバージョンとの衝突でどうすればいいかわからなくなりました。

そんな時に他の代替案を探していたらtauriを見つけました。

### tauri
tauriを使うとフロントエンドのフレームワークをRustなどの言語と統合してデスクトップアプリを作ることができます。

`公式の紹介`
> Tauriは、主要なすべてのデスクトップおよびモバイルプラットフォーム向けの、小さく高速なバイナリを構築するためのフレームワークです。開発者は、ユーザー体験を構築するためにHTML、JavaScript、CSSにコンパイルされるあらゆるフロントエンドフレームワークを統合でき、必要に応じてバックエンドロジックにはRust、Swift、Kotlinなどの言語を活用できます。

https://v2.tauri.app/

## 手順
前置きが長くなりましたが、環境を構築していきましょう

実は以下のコマンドで大体のことが解決できます。

``` zsh
$ npm create tauri-app
```

すると以下のような選択肢が出てきますので、Vueを選びました。
他の選択肢は皆さんのお好みに合わせて構築してください！

``` zsh
✔ Project name · project
✔ Identifier · com.project.app
✔ Choose which language to use for your frontend · TypeScript / JavaScript - (pnpm, yarn, npm, deno, bun)
✔ Choose your package manager · npm
✔ Choose your UI template · Vue - (https://vuejs.org/)
✔ Choose your UI flavor · TypeScript
```

私はVue3.5が大好きなのでVueも最新で入れました。

``` zsh
$ npm install vue@latest
```

環境の準備が終わったら、あとは以下のコマンドを実行するだけです。
``` zsh
$ npm run tauri dev
```

## おわりに
元々はメニューバーやトレーの内容までまとめて書きたかったのですが、まだ安定したものが出来上がらず...

近いうちにtauri v2のメニューバーとの戦いの結果を書いていきたいと思います！！
Elixirでraylibを使ってグラフィック描画してみる

# raylibとは？

`raylib is a simple and easy-to-use library to enjoy videogames programming.`
つまり、ゲームプログラムを作るライブラリ

https://www.raylib.com/

# Elixirでraylib使うには？

Rayexがあります

:::note warn
しかし、いま時点で立方体や線を描画程度しかできません
RayexのC言語のラッパーの部分を追加すれば可能だと認識してます
:::

https://hexdocs.pm/rayex/readme.html

# 事前準備
https://dev.to/andevr/get-started-with-rayexraylib-for-elixir-53gl

# 実験してみる

```diff_elixir:mix.exs
defmodule RayexExperiment.MixProject do
  use Mix.Project

  def project do
    [
      app: :rayex_experiment,
      version: "0.1.0",
      elixir: "~> 1.17",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
+     {:rayex, "~> 0.0.3"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

```

```elixir:lib/rayex_experiment.ex
defmodule RayexExperiment do
  use Rayex

  def main() do
    init_window(800, 800, "window name")
    main_loop(true)
  end

  defp main_loop(true) do
    begin_drawing()
    draw()
    end_drawing()

    Process.sleep(10)
    main_loop(!window_should_close())
  end

  defp main_loop(_), do: nil

  defp draw() do
    x1 = Enum.random(1..800)
    y1 = Enum.random(1..800)
    x2 = Enum.random(1..800)
    y2 = Enum.random(1..800)

    draw_line(x1, y1, x2, y2, %{r: 255, g: 161, b: 0, a: 255})
  end
end

```

# 実行

まず、iexを起動
```bash
$ iex -S mix
```

iexを起動後に

```elixir
iex(1)> RayexExperiment.main
```

# ポイント

- `init_window(800, 800, "window name")` で画面サイズを指定します
- 描画前は`begin_drawing()`
- 描画後は`end_drawing()`
- 後は適度に`Process.sleep`入れます
- このソースは`draw_line`を使ってランダムで線を描画してます

# ハマったこと
deps/rayex/c_src/rayex/rayex.cでエラーでビルドできないので

```diff_c:deps/rayex/c_src/rayex/rayex.c
UNIFEX_TERM is_sound_ready(UnifexEnv *env, UnifexPayload *payload) {
  Sound sound = get_sound_unifex_payload(env, payload);
-  bool res = IsSoundReady(sound);
+  bool res =  false;
  return is_sound_ready_result(env, res);
}
```
に変更でビルドしました


# 操作動画

<iframe width="560" height="315" src="https://www.youtube.com/embed/i9r462ErqLo?si=8bnDqzZmIGXIKr97" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
VSCodeのRで▷(Run Source)ボタンを押してもグラフが表示されないとき

## 解決策
設定で、「Source:Echo」で検索して、チェックをつける。
> R > Source:**Echo**
> ☑ Should the file be executed with echo option set to TRUE by default, i.e. `source(FILE, echo=TRUE)`?

または、▷(Run Source)ボタンを使わず、`Ctrl + Shift + Enter` で全コードをコンソールに送り実行すると、グラフは表示される。
## 背景
▷(Run Source)ボタンを押したとき、コンソールに
```r
source(FILE, encoding = "UTF-8")
```
が送られる。

`source` 関数のオプションに `echo` があり、`echo = TRUE` ならファイルの読み込み後に実行され、過程と結果が表示される。

`echo` のデフォルトは `echo = verbose` となっており、`verbose` のデフォルトは `FALSE` である。

つまり、デフォルトではファイルは読み込まれ実行されても、過程と結果は表示されない。

そこで `source(FILE, echo = TRUE)` にするため、「Source:Echo」にチェックをつける。
【備忘録】システムのWebサーバー安定化のために試したこと

## 背景
私たちが運用するシステムでは、WebサーバーのCPU使用率が1日に1～2回ほど100%近くに達し、その都度オートスケールが発生する状況が続いていました。この影響で以下の問題が発生していました。

- 画面表示に必要なキャッシュが不完全な状態で取得され、特定の画面へ遷移できない
- 最悪の場合、画面が表示されない

これらを改善すべく、以下の施策を試行しました。

---

## 実施した施策

### 1. キャッシュの保存先をS3からEFSへ切り替え
#### 従来の仕様
- **Batchサーバー**がキャッシュを作成し、zip化してS3にアップロード
- **Webサーバー**はS3からキャッシュをダウンロードして解凍

#### 改善後の仕様
- **EFS**を導入し、BatchサーバーとWebサーバーでキャッシュディレクトリをマウント
- Batchサーバーがキャッシュを直接EFSに出力し、Webサーバーはリアルタイムで参照

#### 成果と課題
- キャッシュ関連の欠陥は解消され、アップロード・解凍プロセスも不要に
- しかし、EFSの速度面でのパフォーマンスが問題となり、導入は見送り。速度重視ではEBSの方が適していることを確認

---

### 2. `nice`/`ionice`コマンドの導入
#### 概要
- **nice**: CPU使用率の優先度を設定
- **ionice**: I/O操作の優先度を設定
- キャッシュ処理の優先度を下げ、画面アクセスを優先的に処理

#### 成果と課題
- CPUリソース配分の効果を期待したが、他の優先プロセスがない場合に期待通りの効果は得られず

---

### 3. `TargetResponseTimeForIncrease`の設定調整
#### 概要
- オートスケールのトリガー条件を「応答時間1.5秒以上」から「5秒以上」に緩和

#### 成果と課題
- オートスケール頻度の減少を狙ったが、顕著な改善は確認できず

---

### 4. キャッシュ依存の排除
#### 概要
- キャッシュがない場合でも画面遷移可能なように改修
- 必要な情報が欠ける場合も、最低限の動作を保証

#### 成果
- キャッシュ依存が緩和され、ユーザー体験が向上。改修の効果は大きかった

---

### 5. EC2インスタンスのスペック増強
#### 概要
- インスタンスタイプを1段階アップグレード

#### 成果
- CPU負荷が大幅に軽減され、システムは安定化

---

## 最後に
今回のケースは原因の特定が難しかったため、原因解決ではなく負荷改善施策で安定化を図ろうとしましたが、一筋縄ではいきませんでした。最後にはお金による解決に頼ってしまいましたが、様々な施策を試す中で技術的な引き出しが増えたことを実感しています。

システムの機能改善とサーバーの安定化という両輪をバランスよく回しながら、将来的にはよりコスト効率の良い方法を模索していきたいと思います。
リモート前提の働き方での合宿の活用

# はじめに

本記事は、[さくらインターネット Advent Calendar 2024](https://qiita.com/advent-calendar/2024/sakura)の9日目の記事となります。
本記事では、さくらインターネットのリモート前提の働き方をご紹介させていただきます。
その上で、私が所属するクラウドバックエンドにおける合宿についてもご紹介いたします。

# リモート前提の働き方

さくらインターネットでは、場所に縛られず、どこでも活躍できる環境づくりを推進するために、リモートワーク前提の働き方を採用しています。

https://www.sakura.ad.jp/corporate/corp/work-environment/

公開されている2024年3月の下記データを見ても、リモートワーク実施率は89.9%と非常に高くなっており、出社の必要がある社員以外は、ほぼリモートワークという状況です。

https://www.sakura.ad.jp/recruit/data/

リモートワークでも円滑なコミュニケーションが促進されるように、Slack による非同期的なやりとりと、Zoom による同期的なコミュニケーションを組み合わせて、日々の業務を行っています。
リモートワークにより、例えばクラウドバックエンドのとあるチームでは、東京、大阪、福岡、沖縄の各拠点のメンバーが在籍し、さらに、拠点から離れた場所にお住まいのメンバーも、リモート前提だからこそ、同じチームで日々の開発業務を行うことができています。

# ガバメントクラウドへの取り組み

上述のツールの活用により、日々のチームのコミュニケーションは十全に行われていますが、現在さくらのクラウドが取り組んでいる[ガバメントクラウド](https://www.digital.go.jp/policies/gov_cloud)においては、以下の課題感が生じてくるものとなりました。

- 2025年度末までにすべての要件を満たすことを求められているガバメントクラウドに対して、スムーズにゼロからイチを決めていくスピード感
- 中途採用でご縁があった多くの新メンバーとの、遠慮のないコミュニケーションの速やかな実現

これらの課題感を解決するために、同じ部屋に集まりホワイトボードに図を描いたり、付箋を貼るような柔軟なディスカッションや、顔を合わせてのコミュニケーションの重要性を再発見することとなりました。
上記のコミュニケーションの実現のために、2024年12月現在、クラウドバックエンドの各チームで、半年に一度ほどのサイクルで、合宿を行っています。

# 合宿の活用

クラウドバックエンドの合宿では、まず、合宿前に以下の確認をします。

- 合宿で解決したい課題の確認
- 合宿場所の設定(チームの各メンバーが集いやすい拠点など)
- 合宿のタイムラインですべきことの設定

そして、合宿中は、設定したすべきことに対して、ホワイトボードの前に集まりながら取り組んでいきます。
適宜写真を撮りながら Slack のチャンネルに共有しつつ、決まったことを記録として残します。
また、ランチタイムや懇親会などでの雑談も大切にして、心理的なハードルも下げて、よりスムーズなコミュニケーションも実現していきます。
合宿後は、それぞれの拠点に戻り、ゼロからイチとなったアイデアを元に実装したり、合宿で打ち解けたメンバーと遠慮のないディスカッションをしたりと、いつものリモート前提の働き方を、より円滑に行うものとなります。

# まとめ

本記事ではさくらインターネットのリモート前提の働き方をご紹介しました。
また、クラウドバックエンドで取り組んでいる合宿についてもご紹介しました。
2025年度末までにすべての要件を満たすことを求められているガバメントクラウドの対応のため、合宿をはじめとして、開発を加速する取り組みを今後も活用していく所存です。

# 終わりに

現在さくらインターネットではエンジニア採用を強化中です。

https://www.sakura.ad.jp/lp/recruit-engineer/

もしご興味がありましたら、カジュアル面談も可能ですので、お気軽にご連絡いただけると幸いです。
Cupyのインストールが手間取った話

numpyを使えばいいが、データが大規模になると、GPU計算させたくなる。そこで、cupyを使おうとなるが、躓いた点を紹介する。

# Cupyインストール
そもそもNvidiaのドライバーを入れないといけない。
* ドライバーを入れるためには、Nvidiaコントロールパネルをインストール
* **第一関門:** Studioドライバーをインストールorアップデート。
Game Readyのほうだと、後々エラー出たりしてダメで結局Studioにしたらできた。
* CUDA Toolkitをインストール。このとき、バージョンを覚えておく。
* **第二関門:** コマンドプロンプト等を起動し、pip installする。このとき、必ず先ほどのCUDAのバージョンと合わせる。
```pip install cupy-cuda12x```(バージョン12を入れたなら)
```pip install cupy-cuda11x```(バージョン11を入れたなら)
なお、```nvcc -V```でCUDAのバージョン情報を得られる。
* これでcupyのインストール完了
基本的には、"numpy"または"np"を"cupy"または"cp"に書き換えればGPU計算になる。
``` python:example.py
import cupy as cp
E = cp.eye(4) #4次元の単位行列
print(E)
```
:::note warn
リスト（[1,2,3]など）とcupy配列とは計算できないので、注意！
:::
一次元ベクトルとして使うなら、あらかじめcp.zeros(n)などでゼロベクトルを生成するのが手かも。

分量としてはこれだけだが、そこに気づくまでに何時間も試行錯誤する羽目になったので、こういった先人のエラー記事は大切なんだと気づいた...
U#でサイズの大きい数値配列を扱う

この記事は、[UniMagic Advent Calendar 2024](https://adventar.org/calendars/10877) 9日目の記事です。
~~まあ厳密には関係者じゃない気がするけど、細かいことは気にしたら負け。~~

---

UdonSharpで数～数十MBくらいのサイズの数値配列を扱いたい時のメモ。

サイズが小さい配列であれば、普通に定義すればよい。
しかし、配列のサイズが大きくなってくると、次第にコンパイルに時間がかかり、メモリも必要になってくる。

（こんな感じに100MB越えのcsファイルを作ると、コンパイル時にメモリ不足になる。）

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2320900/9f6d049d-6642-89c3-bb62-1a995680ab71.png" width=70%>

VRCJsonを使う手もあるが、文字列として扱うのでサイズが大きくなりがちである。
また、数値が内部的にDoubleとして扱われるので、そこまでの精度が必要ない時はリソースの無駄になってしまう。

# System.Buffer.BlockCopy
ここで使えるのが、[System.Buffer.BlockCopy](https://learn.microsoft.com/ja-jp/dotnet/api/system.buffer.blockcopy)である。
これを使うと、Byteの配列から他の数値型の配列に値をコピーすることができる。

https://learn.microsoft.com/ja-jp/dotnet/api/system.buffer.blockcopy

コピー元となるByteの配列だが、ワールドデータに含めるのであればTextAssetを使うのがよいと思う。
拡張子を`.bytes`にして保存すれば、Unityがバイナリデータであると認識してくれる。

https://docs.unity3d.com/ja/2022.3/ScriptReference/TextAsset.html

```csharp
using System;
using UnityEngine;
using UdonSharp;

public class ExampleClass : UdonSharpBehaviour
{
    [SerializeField] public TextAsset bigArrayData;

    private uint[] _uintArray;

    void Start()
    {
        // uintは4byteなので、4で割っている
        // 型に合わせて割る数を変える
        _uintArray = new uint[bigArrayData.bytes.Length / 4];
        Buffer.BlockCopy(bigArrayData.bytes, 0, _uintArray, 0, bigArrayData.bytes.Length);
    }
}
```

また、ワールドデータに含めず、インターネット経由にしたい場合は、VRCStringDownloaderの`ResultBytes`を使えばいいと思われる。（自分では未確認）

---

なお、元となるByte配列のデータは、pythonで用意した。
[struct](https://docs.python.org/ja/3/library/struct.html)を用いればいい感じのバイナリデータを作成できる。

https://docs.python.org/ja/3/library/struct.html

```python
import struct

data = [1, 2, 3, 4, 5]

with open("bigArrayData.bytes", "wb") as f:
    # "<": リトルエンディアン
    # "I": uint（ここの文字は数値の型によって変える）
    f.write(struct.pack("<"+"I"*len(data), *data))
```

# 余談
書き終わってから気づいたが、VRC公式ドキュメントにもBlockCopyの記載があった。
（コードだけの分かりにくいものだったので、この記事を書いた意味はあったかな…？）

https://creators.vrchat.com/worlds/udon/data-containers/byte-and-bit-operations/
Point Cloud Surface SOPがジオメトリの自己交差除去に役立つことに気づく前のアプローチ

[前回の記事](https://qiita.com/vxlxv54/items/850c9347b0843cdddbac) で、ジオメトリへノイズを適用した際などに発生する裏返り部分を除去するアプローチを考察していました。

本記事に記載してあるものは、その際に無用であると判断した記述です。失敗の中にもヒントはあるという信条のもと、ここに記録として残します。

シーンデータは前回の記事同様、 [こちら](https://drive.google.com/file/d/1yyLLu9zDV5f8ulT5snQHlmZvnJgFNT8j/view?usp=drive_link "approaches_to_remove_intersects.hiplc") からダウンロードできます。
シーン中の、approach_mesh OBJ 内の右端に置いてある omitted_approach ジオメトリノードが、本記事に該当するものです。

::: note
Point Cloud Surface SOP は、裏返っていると推定される部分をジオメトリ生成対象から除外する挙動をします。そのことに気付いていなかったことが、本記事の記載につながりました。
:::

## 肝となるSOP

Point Cloud Surface SOP を使用します。この SOP は主にフォトグラメトリで使用されるもので、法線を持つ点群をもとにポリゴンを作成します。

![pcsurface.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/2abcc0d2-ad62-c3b2-f074-4bfbee1fc3a4.png)

## アプローチ

このアプローチではジオメトリの表面に点群が必要になります。ですがジオメトリへ直接 Scatter SOP を使用した場合、除去するべき裏返った場所にも点ができてしまいます。そこで以下の方法により点群を用意します。

1. ジオメトリから離れた位置に点群を生成する
1. 点群をジオメトリへ向かって投射する
1. 衝突部分の primitive 法線と投射方向をもとに、その部分の表裏を判定する
1. ジオメトリが表の場合、衝突部分へ点を移動し、その部分の primitive 法線を点へコピーする
（ジオメトリの裏返っていない部分へのみ点群を付着させる）
1. 点群の投射を四方八方から行うことで、裏面以外を点群で包む

### 投射開始位置と投射方向

ジオメトリの外から点群を投射するために、ジオメトリ内に点が生成されないようにする必要があります。

#### 球の生成

Bound SOP はジオメトリを内包する箱を作成しますが、箱ではなく球で作成することもできます。デフォルトでは大雑把なサイズの球になりますが、Accurate Bounds パラメータをオンにすることで、より効率的な球が生成されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/468381a8-b7b2-2480-40f3-da603e54f67a.png)

この球に散布した点群はジオメトリの内部には位置しません。それを球の中心方向へ投射することでジオメトリを点群で包めます。


ですが、そうすると球の中心と外側で点の投射密度が大きく異なり、Point Cloud Surface 適用時にかなりシルエットが崩れてしまいます。そのため、次のようにもうひと工夫します。

### 平面の複製と点群の作成

球面上に平面を置き、その平面へ点群を散布することで、投射時に点群密度が偏るのを多少防ぐことができます。

下図はそのイメージで、左側は球の中心に近づくほど点群密度が高まるのに対し、右側は均等な投射ができていることが判ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/28783304-ce5e-f16f-b130-793f4087d080.png)

そのため、点群生成を次のように行います。

1. Bound で作成した球へ Scatter SOP で点群を作成する
1. その点群へ Copy to Stamp SOP により板のジオメトリを複製する
1. 複製された板へ改めて点群を生成する

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/46616845-b074-59c3-a420-36233a151189.png)

実際には複製した板へ点群を散布するより、板へ散布した点群を複製したほうが高速に処理できるため、サンプルではそのようにしています。

### 衝突部分の裏表を判定

投射時に裏面を避ける仕組みを含めるため、VEX の intersect 関数と primuv 関数を使用します。

<dl>
  <dt>intersect</dt>
  <dd>任意の場所から指定した方向へジオメトリを探し、衝突部分の情報を取得します。引数 dir の長さはジオメトリを探す距離も意味することに注意する必要があります。</dd>
  <dt>primuv</dt>
  <dd>intersect などから入手できる情報を使用して、衝突部分の primitive から情報を取得します。</dd>
</dl>

primuv で取得したジオメトリ法線と、投射した方向との内積がプラスであれば、その衝突面は裏面だとみなせます。裏面に衝突したと判定された点と、そもそもジオメトリへ衝突しなかった点は、不要なので削除します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/ee7451b7-b1be-87a5-fc19-6ff79e8185c4.png)

このアプローチで四方八方から点群を付着させ、法線を取得したうえで Point Cloud Surface を適用するとジオメトリが再構築されます。

### 結果

このアプローチを採った場合の結果は図の通りです。

![result_pccloud_surface.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3930709/ff94d458-8094-205d-a271-2b94c7028f6a.png)
Salesoforceレポートタイプを非表示にする方法

Salesforceでレポート作成したい場合、デフォルトで標準レポートタイプがたくさん表示されており、使わないレポートタイプは非表示にしたいですね

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/fb6ee29f-951f-27a7-5be0-0c71e18837b5.png)





まずはClassic環境にします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4051af2e-88b5-d6ad-4f70-6f7b8a8272d5.png)

そしてClassic環境から
レポート　タブをクリックします


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/4f8bcf0e-55e2-c726-93e2-80b2f6741d6c.png)


次に
非表示にするレポートタイプを選択
をクリックし非表示にしたいレポートタイプをクリックします

「×」がつけば成功です
これでレポートタイプが非表示になります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/a8d394cf-409e-c9e1-1707-662928fdbc8a.png)

これでClassic環境はもちろんですがLightning環境でもレポートタイプが非表示になりました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/762d475c-e8c7-2e3e-c317-b3eb90532923.png)


なおレポートタイプをまた表示させたい場合は再度Classic環境にしてチェックをしましょう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/d6c47d3f-6e12-3b81-0728-f51bae3dd352.png)
変数

### 背景
数字や色などを指定するとき、その値を直接指定する代わりに、値を入れる変数を用いることをScratchでも試してみました。

### Scratch
変数を作成すると、変数の値を代入するブロックが現れました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/92cb9fe4-3416-afd5-a8a1-8a4aa27f9757.png)

「方角用の変数をaとする。
　aにゼロを代入して方角をaに変える。
  aに90を代入して方角をaに変える。
  aにa + 90を代入して方角をaに変える。
　」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/103446/64d00662-98b7-553f-d907-479202eb7fce.png)

最初にコンパスのキャリブレーションのために一周し、
ゼロの向き、90の向き、そして90 + 90 = 180の向きに回りました。

### spheroV2
sphero_edu.pyのメソッドを参考に同様な動作をするスクリプトを作成しました。

```
import time

from spherov2 import scanner
from spherov2.sphero_edu import EventType, SpheroEduAPI
from spherov2.types import Color

print("Testing Starting...")
print("Connecting to Bolt...")
toy = scanner.find_BOLT()

if toy is not None:
    print("Connected.")
    with SpheroEduAPI(toy) as droid:
        print("Testing Start...")
        
        droid.reset_aim()

        droid.set_stabilization(False)

        droid.calibrate_compass()
        time.sleep(1)
        
        a = 0

        droid.set_compass_direction(a)
        time.sleep(1)
        print(a)

        a = 90

        droid.set_compass_direction(a)
        time.sleep(1)
        print(a)

        a += 90

        droid.set_compass_direction(a)
        time.sleep(1)
        print(a)

        print("Testing End...")
```

実行結果はこちらのようになりました。
```
git\spherov2.py\spherov2\test>python BoltTest_compass2.py
Testing Starting...
Connecting to Bolt...
Connected.
Testing Start...
0
90
180
Testing End...
```

### まとめ
（pythonに慣れていたので、）Scratchで変数の代入してみました。
変数を作成するとセッターが現れるのが面白かったです。
Nerves システム最新リリースの概要 (v1.29.1)


## はじめに

Nerves の共同開発者である Frank Hunleth 氏が[Elixir Forum][elixir_forum_post]で最新の Nerves システムリリース（v1.29.1）の情報を共有されていました。

このアップデートには、Erlang/OTP の最新バージョン対応や Buildroot 更新のみならず、他にもいろいろ**エキサイティング**な更新が含まれています。

## 主な更新内容

### Erlang/OTP 27.1.2 へのアップデート

Nerves が最新の [Erlang/OTP 27.1.2][erlang_release] に対応しました。これにより、パフォーマンスと安定性がさらに向上しています。

### Buildroot 2024.08.2 への更新

Buildroot が最新版である [Buildroot 2024.08.2][buildroot_release] にアップデートされました。ツールチェーンやビルドシステムが刷新され、基盤がさらに強化されています。

### 802.11x 向けの PKCS11 サポート追加

ハードウェアセキュリティモジュール（HSM）がサポートされるようになりました。これにより、802.11x 認証におけるセキュリティ機能が強化されています。

### XLA サポートの修正

加速線形代数（XLA）の利用に関する問題が修正されました。この改善により、機械学習関連プロジェクトの取り組みがスムーズになります。

## 「特にエキサイティング」アップデート

> Some of the most exciting updates are in the official Nerves systems, though.

最もエキサイティングなアップデートは、公式の Nerves システムに関連するものです。

### リアルタイム Linux の PREEMPT_RT パッチ

リアルタイム Linux（PREEMPT_RT）パッチが導入されました。このパッチにより、カーネル全体のレイテンシが低減され、リアルタイム I/O 応答時間が向上します。

この機能をフル活用するには、Linux カーネルや Erlang のオプションを使ってリアルタイムコアを割り当てる必要があります。

https://wiki.linuxfoundation.org/realtime/start

### libcamera への移行

Raspberry Pi ユーザーにとって重要なのは、MMAL ベースのカメラドライバから **[libcamera][raspberry_pi_camera]** ベースのものに移行したことです。この変更は、すべての Raspberry Pi システムに影響を与えています。これにより、長年利用されてきた **[picam][picam]** ライブラリが正式に非推奨となりました。

Nerves システムには、[Raspberry Pi libcamera ドキュメント][raspberry_pi_camera] に記載されているサンプルカメラアプリケーションが含まれています。ただし、現時点ではこれらを簡単に活用できる Elixir 向けのラッパーライブラリは存在しません。そのため、libcamera の恩恵を受けつつ、最新のコンピュータビジョンやカメラ技術を取り入れるには、アプリケーション側での工夫が必要です。

## Frank さんからのお願い

Nerves システムのサポート対象プラットフォームやデバイスが非常に多いため、全てを完全に網羅するのは簡単ではありません。以下の点で協力をお願いされています。

1. **使用中の Nerves システムのリリースノートを確認してください！**  
   プロジェクトに影響を与える可能性があるため、各システムの[変更履歴][nerves_system_br_releases]をご覧ください。

2. **フィードバックをお寄せください！**  
   万が一、不具合や回帰が発生した場合は、ぜひ報告をお願いします。Nerves プロジェクトをさらに良いものにするために、フィードバックがとても重要です。

## Frank さんからの感謝

今回のリリースサイクルで Frank さんは、以下のような課題を乗り越えたそうです。

- **Web ブラウザのキオスクモード対応**
- **リアルタイム Linux の導入**
- **機械学習サポートの拡張**
- **初の GCC バグへの対応**

これらの成果は、Nerves ユーザーコミュニティの協力なしでは達成できなかったそうで、関わってくださった全ての方に感謝を伝えたいとのことです。

## おわりに

今回のリリースは、セキュリティやリアルタイム性の強化に加え、最新技術の活用を可能にするアップデートが盛り込まれています。  
詳しくはご自身の目で[Elixir Forum][elixir_forum_post]や公式の[変更履歴][nerves_system_br_releases]をご覧ください。

![toukon-qiita-macbook_20230912_091808.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/82804/fd5c55ec-4fe0-8af6-59bc-bab1ef3d182b.jpeg)

<!-- begin-reusable-link -->

[elixir_forum_post]: https://elixirforum.com/t/nerves-system-releases/25621/16?u=mnishiguchi  
[erlang_release]: https://erlang.org/download/OTP-27.1.2.README.md  
[buildroot_release]: https://lore.kernel.org/buildroot/871pzex7gn.fsf@dell.be.48ers.dk/T/  
[raspberry_pi_camera]: https://www.raspberrypi.com/documentation/computers/camera_software.html#libcamera  
[nerves_system_br_releases]: https://github.com/nerves-project/nerves_system_br/releases  
[picam]: https://hex.pm/packages/picam  

<!-- end-reusable-link -->
ネットの力を借りてAIに多角的視点を持たせられた話

こんにちは人間です
AIをどう活用するかを常日頃考えてる人です

# 概要
chatgptなどのAIに１つの目線に立たせて回答させるということを
やっていましたが、それが面倒くさいので、
これを自動化する仕組みを作りました。

# 環境
windows11
python 3.11.7
cuda 12.4

**ライブラリ**
|kind |version |
|:--|:--:|
|flask |23 |
|transformers |32 |

# やったこと

## 視点の作成
  
### 視点のテンプレートから選択
頻繁に使用する観点をすぐに選択できるようにテンプレートとして利用できるようにします。

### 視点をネットから拾ってくる
テーマについてGoogle Custom Seach APIで検索して
結果をAIに渡して視点に変換してもらいます

## 推論(AI処理)

### 視点をAIに推論してもらう
[△というテーマに~という観点で述べてください]
というようなプロンプトをAIに投げそれを返す
プログラムを書きました。

## ファインチューニング(教師あり学習)
先ほどのような推論の結果で他のAI(chatgpt,llama,qwenのhuggingFace Chatなど)で
評価してもらい、その結果のよかったものを整理して作った
回答と質問のデータセット(サンプル数100)
を作り学習させました。



# 参考記事

https://goodsystem.jp/development/google-search-results-without-being-illegal.html

https://cockscomb.hatenablog.com/entry/streaming-with-huggingface-transformers
TypeScriptのsatisfies演算子を用いて網羅性チェックをする話(個人メモ)

# はじめに
TypeScriptを最近学んだので振り返り記事になります。
TypeScript4.9の内容なので今更感はありますがご了承下さい。

# 汎用例
通常犬、猫の種類を表現する時はbreed、その他の動物ではspeciesと呼びます。
そのため以下のように個別のプロパティを設けて実装することにしました。
```typescript
type Dog = {
  type: "dog";
  breed: string;
};

type Cat = {
    type: "cat";
    catBreed: string;
}

type Hamster = {
  type: "hamster";
  species: string;
};

type Animal = Dog | Cat | Hamster;
```

プロパティ毎にコンソールの出力内容を変更したいとします。
```typescript
const printAnimal = (animal: Animal) => {
    switch (animal.type) {
      case "dog":
        console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
        break;
      case "hamster":
        console.log(`こちらのハムちゃんの種類は${animal.species}です`);
        break;
      /** Catの分岐を書き忘れた。。。 */
    }
}
```
このようにIf文やswitch文を用いて実装するとパターン漏れが発生して、
テスト時にやっと気づくみたいな事がよくあります。

TypeScript 4.9からは便利な`satisfies`演算子なるものが、
実装されて以下のようにコンパイル時に気づくことができます。
`satisfies`は直訳すると`必要性を満たす`です。
```typescript
const printAnimal = (animal: Animal) => {
    switch (animal.type) {
      case "dog":
        console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
        break;
      case "hamster":
        console.log(`こちらのハムちゃんの種類は${animal.species}です`);
        break;
      default:
        // 型 'Cat' は想定された型 'never' を満たしていません。ts(1360)
        animal satisfies never;
        break;
    }
}
```

以前はnever型の特性を利用して以下のようなコードを書いていましたが、
不要な変数に値をセットしていたり直感的に理解しにくいコードになってしまうため、
`satisfies`演算子を用いて網羅性チェックをする事をお勧めします。
```typescript
const printAnimal = (animal: Animal) => {
    switch (animal.type) {
      case "dog":
        console.log(`こちらのワンちゃんの犬種は${animal.breed}です。`);
        break;
      case "hamster":
        console.log(`こちらのハムちゃんの種類は${animal.species}です`);
        break;
      default:
        // 型 'Cat' を型 'never' に割り当てることはできません。ts(2322)
        const check:never = animal;
        break;
    }
}
```

# 参考文献
https://typescriptbook.jp/reference/statements/never#never%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E7%B6%B2%E7%BE%85%E6%80%A7%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF
楽しい駆動開発（FDD）～EMとしてチームの楽しいをマネジメントする～

# 楽しい駆動開発（FDD）～EMとしてチームの楽しいをマネジメントする～

## はじめに  
私はもともとメンバーとしてチームにアサインされましたが、組織が拡大する中で役割が次第にマネージャー寄りになり、現在はプレイングマネージャーとして開発業務とエンジニアリングマネージャー（EM）としての評価やマネジメント業務を並行して行っています。

きっかけは、会社のリーダー研修でメンバーにアンケートを取った際、「引き続き仕事を楽しむ姿勢でリードしてほしい」というコメントをもらったことでした。この言葉を受けて、改めて自分自身を振り返ると、もともとエンジニアリングというものが好きで、楽しんで仕事をしている自覚がありました。

そのため、EMとしての軸を「エンジニアリングの楽しさ」に設定し、「楽しい駆動開発（Fun Driven Development）」と名付けて施策を進めてきました。本記事では、その具体的な施策について紹介します。


## 施策  

### 1on1  
個人が楽しいと感じるポイントは人それぞれ異なるため、一人ひとりに向き合う必要があると考え、2週間に1回の1on1を実施しています。その中で、特に「楽しかったこと」に焦点を当てるようにしました。このように楽しい瞬間を振り返ることで、メンバーが自分の好きなことや得意分野を再認識するきっかけにもなっているのではないかと考えています。

私自身も1on1を通じて、メンバーがどのように楽しいと感じているかを知ることで、より適切なタスクアサインやサポートができるようになったと思います。

---

### Fun Done Learn  
スクラムでの開発の中で、振り返り手法としてFun Done Learnというフレームワークを取り入れています。このフレームワークでは、「楽しいこと（Fun）」「達成したこと（Done）」「学んだこと（Learn）」を共有し合うことが特徴です。

特に「楽しいこと」にフォーカスすることで、チーム全体がポジティブな文化を育む一助になると考えました。この取り組みが、メンバーそれぞれの楽しい瞬間を意識的に振り返るだけでなく、チーム全体で楽しい体験を共有する文化の醸成につながっているのではと期待しています。

---

### スプリントレビュー  
スプリントレビューでは、開発者自身がデモを行うようにしています。これは、直接的なリアクションを受け取ることで開発者が自分の成果を実感し、モチベーションを高められると考えたためです。しかし、反応のないデモは楽しくないため、ステークホルダーに積極的にリアクションしてもらえるように事前に根回しを行っています。

このようにステークホルダーとの連携を強化することで、レビュー自体が楽しい場になるよう工夫を重ねています。

---

### 技術記事つぶやきチャンネル  
チーム内で技術的な知識や気づきを気軽に共有できる場として、Teams上に「技術記事つぶやきチャンネル」を作りました。投稿のハードルを下げるため、「短文でもOK」「リンクを貼るだけでもOK」とするルールを設けています。

しかし、現状では自分と特定のメンバー1人しか投稿していない状況が続いています。マネージャーの自分が「もっと投稿しよう」と言うと指示のように受け取られ、楽しくなくなる可能性があるため、自然に参加が広がる方法を模索しているところです。

---

### 外部の勉強会への参加  
「世間一般的に、このチームや施策ってどうなんだろう？」という疑問を解消するため、外部の勉強会に積極的に参加しています。特に翔泳社やFindyが主催する無料の勉強会を中心に、自分が登録してメンバーを誘う形を取っています。これは、メンバー自身が言い出しにくい場合があると感じたためです。

勉強会では、自分たちの環境が比較的モダンだと感じてくれる人もいれば、仕組みを導入したいと言ってくれる人もいます。また、Ask The Speakerのセッションでは、普段言えない不満や疑問が解消されるなど、それぞれが楽しんで参加してくれていると思います。


## 終わりに  
これらの施策の中には、すんなりとうまくいったものは少なく、課題も多くあります。私自身、エンジニアとしての経験は長いですが、マネージャーとしての経験はまだ浅いため、間違いや試行錯誤も多々あります。

それでも、楽しい駆動開発（Fun Driven Development）を軸に施策を続けることで、少しずつチーム全体に「楽しい」を増やしていくことができたと思います。この取り組みが、他のチームやマネージャーの参考になれば幸いです。
表データをデータベース(DBeaver)に取り込む - データ分析記録#1

## 概要
ほぼ初心者の私がデータ分析できるまでの記録を書き留めています．

ここでは分析するにあたり，データを正しく整理するための前処理となるデータベースに，扱うデータを取り込むところから始めます．DBeaver内のPostgreSQLをデータベース処理として使っていきます．

## はじめに
よく分かってなくて，それでも差支えのない部分はそのままにしていることがあります．
ちゃんと書けていないことがあるかもしれませんが，ご了承ください．
何かお気づきの点があれば，お気軽にコメントくださるとうれしいです．

#### きっかけ
大学にてある企業の方からスーパーでの購買に関するデータを預かり，そのデータを基にデータ分析を行う機会があったのが，一つのきっかけです．

今まで授業では少し触れたもののそんなに自分の身になっていない感がどうしてもあったため，せっかくだからちゃんとデータを扱えるようになりたいと思い，やっています．

## 元データはどんなデータ？
#### ファイル形式
- Microsoft Access Database(.accdb)形式のデータ
- .accdb形式からExcel(.xlsx)形式に変換されたデータ

この2種類の形式のデータが用意されている．

#### データ内容
- ある年の3か月分のスーパーでの購買に関するデータ
(企業さんから預かったデータのため詳しいことは言えない)
- データ量は（私的には今まで扱ったことがない）250万行前後が3か月分

## 1. ファイル形式を.csvに変換
MicrosoftのAccess Databaseは使ったことが無いので，今回は大学の授業で少し使ったことのあるDBeaverをデータベースとして使用する．元データをDBeaverにインポートしたいので，csvファイルを作成する．

#### Access Databaseからcsvファイルをつくる
Access Database内の上のタブにおいて **外部データ > テキストファイル** でエキスポートできる仕組み(GUI)が整っているので，csvファイルだがテキストファイルとして保存し，ファイル名の最後の.txtを.csvに打ち変えて完了すれば変換できる．

#### Excelからcsvファイルを作る
Excelでは**名前を付けて保存**で拡張子（ファイル形式）を.csvに変更して保存することでcsvファイルができあがる．

## 2. DBeaverにインポート
ここからDBeaverでの操作となる．※ DBeaverでPostgreSQLに接続する方法は省略しています．

スキーマ内に複数のテーブルを作りたいので，**スキーマ > テーブル** を新しく作成していき，テーブルを右クリックして **データのインポート** を行う．

作成したcsvファイルをファイルから選んで実行していくと，csvファイルに問題が無ければカラム名，各列の型も含んだがテーブルが作成され，データベースへの取り込みは完了となる．

::: note warn
しかし，私が取り込んだデータの場合，
DBeaverにインポートする際あるエラーが出て行き詰った...
:::

### エラー内容
    integer out of range
ある行に対するエラーメッセージであり，整数型の列において扱えない範囲の数値（大きすぎる数）があるよーとのことだった．

ここで該当のデータを見ると，その数値はラベルとしての値で，その値を使って計算したり昇順に並べ替えたりという操作は必要なかったため，この値を数値型としてではなく文字列型として扱うようにすることでエラーに対処できた．

私の場合，DBeaverに取り込む前にExcelで該当する列に対して **数値 > 文字列** に変更した．

::: note alert
ただし，あまりにも大きい値の場合数値から文字列に変換する際，指数表記になることがあるので注意が必要．
これだと，DBeaverでインポートする際に再び違うエラーが出ることになる．
:::

## 3. DBeaverを扱う際の注意点
SQL文でテキストを打ち込んで実行する際は別だが，DBeaverに読み込んだデータに対して何か変更を行う場合，実行を行わないと変更されていないことがある．

例えば...
- テーブル名の変更
- データをインポートした

など，この際 `Ctrl` + `S` でその都度更新しなければエラーが出る原因になる．

SQL文で実行する代わりに，簡単なボタン操作をするだけでは完全に変更できていないのでセーブして実行までするよう注意が必要．

（ただ面倒で忘れてしまう...何か知っている方いたら教えてください）

## 終わりに
無事データベースにデータを取り込めたので，次はデータ分析に移りたいところ...
（主キーとかの設定がまだ良く分かってないので，そのうちまたやります）

現時点で，データベースからこれから分析していくRにそもそも接続できるのか全く分からない．まずデータベースってどこにデータが保存されてるのか，そこからよく分かっていません．

とりあえずデータベースに取り込めたので，空白のデータとか不要なデータとかそういうのを整理していく方針です．