OmniAICreator/Qiita-1.07M huggingface dataset:
クラスが循環参照しそうなときの回避策

# クラスが循環参照しそうなときの回避策

## はじめに

オブジェクト指向プログラミングでは、実装を進めて機能拡張していくほどにクラス間の関係が複雑になっていきます。
そのクラス間の関係において、特にクラスの循環参照はかなり危険です。
クラス間の関係のアンチパターン（？）と言うほどのものでもありませんが、循環参照は一方の変更によってもう一方が追従して変更し、その変更によって…といったように無限ループを引き起こしてしまったりと実行時エラーを引き起こしうるため、やはりリスクが高いものだと考えます。
ツリー構造とかだとあった方が便利なので、親が子を参照して子が親を参照する、といったことはありますので、一概に全部だめとは言い切れません。ただ、避けられるのであればやはり避けたいものです。

そこで、クラスが循環参照しそうなときの考える順番および回避策を自分なりに言語化・整理してみました。他の人にも役立つと幸いです。

## 回避策

### ①クラスの責務を見直して単一方向の参照だけにできないか考え直す

まず考えるのは、単一方向の参照に減らせないか？だと思います。
アプローチとしては、C#の場合は実行してほしいActionを渡したり、あるいはイベントにハンドラを登録するなどすれば、参照を切れるかと思います。
また、製品開発などきっちり進めている場合はほぼない状況かと思いますが、PoCの試作中など柔らかい状況だと仮実装だったりして使ってないクラスが残っていたりするかもしれません。コードの整理もかねて改めて本当に使っているのか、参照が必要なのかを見直すのも必要かもしれません。

### ②循環参照しそうなクラスの間にクラスを挟んでみる

次に考えるのは、循環参照しそうなクラスの間にクラスを挟んでみる、です。
例えば、いわゆるファサードパターンのように、循環参照しそうなクラスを所有、あるいは参照するクラスを一つ用意すれば循環参照を取り除くことができます。
または、イベントアグリゲータパターン（イベントを集約するサービスを用意して、そのサービスを介してイベントをやり取りする考え方）を用いて、あくまで依存するのはイベントを表すクラスに依存し、イベントの発行者・受信者を直接結び付けないようにするのもよいかと思います。
循環参照を切るために他のクラスを用意することが、割りと多いパターンな気がします。

## 補足

ChatGPTに聞いたところ、```インターフェイスを導入する```といった方法もあるようです。確かに依存する対象はインターフェイスになりますが、結局プログラムを動かすときはそのインターフェイスを実現しているクラスをインスタンス化して動かします。そのインスタンス化したオブジェクトが実体として参照しあっているのであれば、実質循環参照になってしまうのでは？と思いました。
例えばParentクラスがIParentインターフェイスを実現し、ChildクラスがIChildインターフェイスを実現していて、ParentはIChildを参照、ChildクラスがIParentを参照している場合などです。

また、元々のあるべき姿を考えると、インターフェイスはあくまで振る舞いを表すものですので、参照を切るために無理に使うものではないとも考えます（書きながら、「②循環参照しそうなクラスの間にクラスを挟んでみる」と相反しているようにも思いましたが、そこの言語化はまだできていないです。。。）。

## おわりに

今回は、オブジェクト指向プログラミングでクラスが循環参照しそうなときの回避策について考えてみました。
クラス間の関連をうまく整理するというのは中々難しい気がしますが、設計力につながるポイントのようにも思います。
日々鍛錬していきたいですね。
キーボードの記号の正式名称の一覧

### Ctrl＋Fでページ内検索して使ってください。
| 記号       | 正式名称                           | 
| :--------: | :--------------------------------: | 
| ！         | 感嘆符、エクスクラメーションマーク | 
| ”         | ダブルクォーテーション             | 
| ＃         | シャープ、いげた                   | 
| ＄         | 	ダラー、ドル、ドルマーク          | 
| ％         | パーセント                         | 
| ＆         | アンパサンド、アンド               | 
| ’         | （シングル）クォーテーション       | 
| （         | かっこ、パーレン                   | 
| ）         | かっことじ、パーレン               | 
| ＝         | イコール                           | 
| ー（全角） | 長音記号                           | 
| ～（全角） | 波形                               | 
| ~（半角）  | チルダ、チルダー                   | 
| ＾         | カレット、キャレット、ハット       | 
| ｜         | 縦線、パイプ                       | 
| ￥         | 円マーク、円                       | 
| ｀         | 逆クォーテーション                 | 
| ＠         | アットマーク                       | 
| 「         | かぎかっこ                         | 
| 」         | かぎかっことじ                     | 
| ｛         | 中かっこ                           | 
| ｝         | 中かっことじ                       | 
| [          | 大かっこ                           | 
| ]          | 大かっことじ                       | 
| ＋         | プラス                             | 
| ー（全角） | 長音                               | 
| ；         | セミコロン                         | 
| ：         | コロン                             | 
| ＜         | しょうなり                         | 
| ＞         | だいなり                           | 
| ,          | コンマ（蘭語）、カンマ（英語）     | 
| .          | ピリオド                           | 
| 、         | とうてん（読点）                   | 
| 。         | くてん（句点）                     | 
| /          | スラッシュ                         | 
| \          | バッグスラッシュ                   | 
| _          | アンダーバー                       | 
| ・         | なかぐろ（中黒）                   |
Keycloakにログインできなくなった時の対策

先日 keycloak に Duo security の 2FA を追加しました。
https://qiita.com/uturned0/items/8f45ce492ec59680f9f2

client=`security-admin-console` にも適用したのでkeycloak admin consoleに入る時もduoが必要です。ただ、もしduoのサービスが障害で落ちていたら console に入れなくなるので、その時に Duo を無効化する方法を調べました。

# prerequicites

Keycloak 22を使ってます。v19までのWildflyでは非対応なので、quarkusになってない人はupgradeしましょう。

参考 https://qiita.com/uturned0/items/e9256c48ccba6f588d79



# How to update Authentication flow

方針として、admin consoleにかかってるauthentication flowをデフォルトに戻すことにします。そうすればid/pwだけでログインできるようになります。

keycloak serverにloginします。

```rb
cd /opt/keycloak/bin
./kcadm.sh config credentials --server http://localhost:8080 --realm master --user admin
admin のパスワードを入力します。

# security admin console の client id を探す
./kcadm.sh get clients -r master --fields id,clientId | grep -B1 security-admin-console

ADMIN_CLIENT=58333d37-3729-4256-a8e3-d1640903caa7
 
# 今のauthenticaton flowを確認する
./kcadm.sh get clients/$ADMIN_CLIENT -r master | grep -A2 authenticationFlowBindingOverrides


# defaultのauthentication flowを探す
./kcadm.sh get authentication/flows -r master | grep -B1 '"alias" : "browser"'
  "id" : "8934619f-1111-484a-8da4-36c86a41dd26",
  "alias" : "browser",

8934619f... がbrowser(Duoなし)のauthentication flow。それでupdateする

DEFAULT_FLOW=8934619f-1111-484a-8da4-36c86a41dd26

 # flowを上書き
./kcadm.sh update clients/$ID -r master -s "authenticationFlowBindingOverrides={\"browser\":\"$DEFAULT_FLOW\"}"
```

これで id/pwだけでloginできるようになりました。

当然ですが緊急時の作業なので利用にはお気をつけを。


#  password reset
ちなみにこれでユーザパスワードはリセットできますが、先にloginしないとできないので、admin password忘れた場合はこれではできません。

```rb
./kcadm.sh get users -r {realm-name} -q username={username}

./kcadm.sh update users/{user-id} -r master -s "credentials=[{type:'password', value:'new-password', temporary:false}]"
```

DBのadmin userを消して、keycloak起動し直すときにKC_ADMIN_PASSWORDかなんかの環境変数で新たにユーザ作ってもらうしかないんじゃないかと。
闘魂Elixir ── Advent of code 2023 Day 1 Part 1 を Livebook で楽しむ

<b><font color="red">$\huge{元氣ですかーーーーッ！！！}$</font></b>
<b><font color="red">$\huge{元氣があればなんでもできる！}$</font></b>

<b><font color="red">$\huge{闘魂とは己に打ち克つこと。}$</font></b>
<b><font color="red">$\huge{そして闘いを通じて己の魂を磨いていく}$</font></b>
<b><font color="red">$\huge{ことだと思います}$</font></b>

https://qiita.com/advent-calendar/2023/elixir

## はじめに

というわけで @torifukukaiou さんのフォロワーです

~~パク~~ リスペクトです

https://qiita.com/torifukukaiou/items/ca63a2272c409e79a80f

Elixir Livebook で Advent of Code 2023 の問題を解いてみます

https://adventofcode.com/2023

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

https://github.com/RyoWakabayashi/elixir-learning/blob/main/livebooks/aoc/2023/2023_day1_part1.livemd

問題はこちら

https://adventofcode.com/2023/day/1

## セットアップ

Advent of Code 専用の Livebook 用モジュールが存在ます

その名も Kino AOC です

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

## 入力の取得

Kino AOC をインストールすると、 Advent of Code Helper のスマートセルが使えるようになります

![スクリーンショット 2023-12-21 17.29.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/f6128291-2bdf-feef-ff67-b4043ac48f0a.png)

スマートセルを追加すると以下のようなフォームが表示されます

![スクリーンショット 2023-12-21 17.30.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/7778f024-2e01-c051-91e4-c8a6f72cd597.png)

YEAR と DAY をドロップダウンから選択します

SESSION の値は、というと思い切った方法で取得します

Advent of Code のサイトにログインしたあと、開発者ツールで Cookie を参照し、 `session` に格納されている値をコピーしてください 

![スクリーンショット 2023-12-21 17.33.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/776d971f-7ce7-234f-24f0-90080efa3197.png)

Livebook で `SESSION` の入力エリアをクリックするとモーダルが開きます

Name　に適当な値を入力し、 Value にコピーした値を貼り付けて +Add ボタンをクリックします

![スクリーンショット 2023-12-21 17.35.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/20c4abb9-9d21-d56c-f72f-1a343fe2800f.png)

これで準備完了です

スマートセルの左上 Evaluate をクリックしてください

![スクリーンショット 2023-12-21 17.37.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/d1d55902-f124-d70b-3282-4a102c2d5140.png)

以下のようにパズルの入力が取得できています

![スクリーンショット 2023-12-21 17.38.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1485835/31c36bb2-2fe2-3595-c4c8-e9cd5b97ef2b.png)

スマートセルの ASSIGN TO で指定した変数に値が入っています

```elixir
puzzle_input
```

実行結果
```elixir
"9dlvndqbddghpxc\nrtkrbtthree8sixfoureight6...
```

## 私の答え

私の答えです。
折りたたんでおきます。
▶を押して開いてください。

<details><summary>details</summary>

```elixir
puzzle_input
|> String.split("\n")
|> Enum.map(fn line ->
  digits = Regex.scan(~r/[0-9]/, line)
  first = digits |> hd() |> hd()
  last = digits |> Enum.reverse() |> hd() |> hd()
  String.to_integer(first <> last)
end)
|> Enum.sum()
```

正規表現で数字を抜き出し、先頭と末尾を結合しました

</details>

## まとめ

Advent of Code のためのモジュールまであるとは、さすが Livebook です

Day 1 Part 2 はこちら

https://qiita.com/RyoWakabayashi/items/3061e0b86ccf659c32fd
読みやすい議事録とは[1~3年目にオススメ]

# はじめに
新卒3年目の社会人です。ウォーターフォールの案件で、お客様との会議内容を議事録にして納品したので、その際に意識したことを記載します。
特に新入社員の方や3年目までの比較的若いメンバー向けの記事となっています。
自分自身、議事録について少し認識が甘く、非常に勉強になった部分を実際の案件で用いた内容に沿って、下記にまとめます。


##### お急ぎの方へ
上から基本的なことについて記載しており、最後に私が実際のプロジェクトで記載していた内容を書き落としているので、急いでいる人は最後の部分だけコピペしてください。

***

### 議事録の目的
まず初めに、一般的な議事録を作成する目的を3つ下記に示します。目的を意識することで作成するものの出来が変わるので議事録に限らず、ドキュメント等を作成する際は目的を明確にします。


1. 情報の記録: 会議での議論と意思決定の内容を正確に記録する。

2. 責任の明確化:誰がどのような意見を出し、どのような決定がされたのか記録する。

3. 行動の管理: 会議までのアクションと会議後のアクションを記録する。

***

「情報の記録」では、参加者はもちろん、参加できなかった人が議事録を見るだけでどのような会議だったのかわかるような議事録にすることが良いでしょう。

「責任の明確化」を行うことで、後で紛争や混乱が生じるのを防ぎます。

「行動の管理」は、誰がどのようなアクションを担当するかが記録することで、後でアクションの進捗状況を確認することができます。会議では、できなかった理由等も聞き出し、記録しましょう。そうすることでネクストアクションへの改善点となります。

***

### 議事録作成で注意すべきこと
ここが最重要項目です。下記の2点は絶対に行ってください。

統一した書き方：プロジェクト間で一貫性のある議事録にする。書き方を途中で変えない。
フォーマット：お客様の要望やPMに十分に確認して、読んでもらえるフォーマットにする。

***

### 議事録で書くべき項目
下記に、実際の案件の議事録で記録していた項目を記載します。これらを記載しておけば、最低限の項目は抑えられているでしょう。ただし、これは私が経験したお客様とPMの手法で記載していた内容なので、下記の項目を持ってお客様やPMにヒアリングし、過不足がないか確認することが必要です。

会議名：
議題（アジェンダ）：
日時、場所、出席者：
起票者、起票日：
最終更新者、最終更新日：
配布資料名、配布先：
会議内容：
決定事項：
宿題事項（ToDo、課題内容）、担当者、期限：
次回会議開催予定（議題、日時、場所）：
署名欄（PM名、担当者名）：

***

#### (番外編)議事録を早く作成するために、、、
お客様とPMに必要な項目を確認したら、それらの項目をテンプレート化しましょう。
テンプレートファイルを作成することで、議事録作成のスピードが爆速になります

また、出席者や会議内容等の項目では「敬称略とすること」、「発言者に個人名を書かないこと」なども議事録全体がシンプルになり、読みやすくできます。
***

## 会議内容で書くべき項目
議事録の本文にあたる会議内容では、以下の3つのことを意識しましょう。
1. 何について話しているか
2. その結論
3. ダラダラ書かない

上記の3つが意識できれば、何も問題はありません。
他のプロジェクトの議事録等を見ることもありますが、
・何について話しているか明確でない
・関係ない会話を記載している、
という議事録の場合は、振り返ったときに非常に読みづらい議事録となります。

***

### 議事録テンプレート
ここでは、上記でテンプレート化した項目を書き出します。これらをwordにコピペして利用するのも良いでしょう。

以下、ヘッダーで記載する項目

会議名：プロジェクト名　第◯回xxxx定例会議
議題（アジェンダ）：
　1. 進捗について
　2. 連絡、確認事項について
　3. 会議体について

日時、場所、出席者：
　日時：20yy/mm/dd（曜日）13:00~15:00
　場所：aaa株式会社様bbbビル　第２会議室
　出席者（敬称略）：
　　　[aaa株式会社　　ccc部]xx、yy,zz
　　　[アプリケーションベンダー]dd,ee
　　　[ネットワークベンダー]ff,gg
　　　[クラウドベンダー]hh,ii

起票者、起票日：
　　　起票者：ii
　　　起票日：20yy/mm/dd（曜日）13:00~15:00

最終更新者、最終更新日：
　　　最終更新者：hh
　　　最終更新日：20yy/mm/dd（曜日）13:00~15:00

配布資料名、配布先：
配布資料名：
　　　1. 第◯回xxxx定例会議資料名（配布者クラウドベンダー）
　　　2. 課題管理表名（配布者クラウドベンダー）
　　　3. ToDo管理表名（配布者クラウドベンダー）
配布先：プロジェクト関係者

***
以下本文となる部分

会議内容：
文中は敬称略
＜進捗報告について＞
　　　WBSについて
　　　　　プロジェクト全体に関わる遅延の発生はない

　　　課題管理表について
　　　　　No.１　xxxの件について
　　　　　　　　　　yyyで対応中である（クラウドベンダー）

　　　ToDo管理表について
　　　　　全10件のうち、完了7件、対応中2件、新規1件

以下、連絡、確認事項について
　　　＜アプリケーションベンダー作成資料について＞
　　　　　先週以来した資料は、いつ送付可能か（aaa）
　　　　　　　今週金曜日午前中までに送付する（アプリケーションベンダー）
　　　　　　　　　承知した（aaa）

決定事項：
　　　特になし
    
宿題事項（ToDo、課題内容）、担当者、期限：
　　　宿題思考：資料の送付
　　　担当者：アプリケーションベンダー
　　　期限：今週金曜日

***
以下、フッターで記載する項目

次回会議開催予定（議題、日時、場所）：
　　　議題（アジェンダ）：
　　　　　1. 進捗について
　　　　　2. 連絡、確認事項について
　　　　　3. 会議体について
　　　日時：20yy/mm/dd（曜日）13:00~15:00
　　　場所：aaa株式会社様bbbビル　第２会議室

署名欄（PM名、担当者名）：
　　　PM署名：hh
　　　担当者署名：ii
rex0220 関連レコード集計プラグイン 他アプリの完了をセット

[関連レコード集計プラグイン](https://qiita.com/rex0220/items/8cbe764670b0e6431a42)で、他アプリの完了をセットする例です。

# 概要

架電リストアプリに、３回レコード登録するか、または架電状況に完了が選択された場合に、該当する会社の「完了」項目に "完了" をセットします。

関連レコード集計プラグインは、レコードの集計を行うプラグインですが、数値の集計機能と kintone の計算項目を使って、「完了」項目に "完了" をセットします。

- 顧客リスト
    - 架電：数値項目　関連レコード集計プラグインの集計先項目
        - 架電状況が "完了" の場合、3 、その他の場合 1 に変換して集計。
- 完了：文字列項目　自動計算を設定
    - IF(架電>2, "完了", "")


架電リストに完了があると、3 に変換されて集計し、自動計算で "完了" がセットされる。
※架電リストに完了があるかレコードが３以上の場合に、自動計算で "完了" セット

![2023-12-21_17h26_49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/a8fb7b63-1d67-7bab-23b0-6549660f14cc.png)

![2023-12-21_17h18_52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/5090a1ca-d432-06fa-838f-e5c83e27f141.png)

# 関連レコード集計プラグインの設定

![2023-12-21_17h30_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/b0aeaea6-d122-040f-e42c-0610078b500e.png)

- 集計項目
![2023-12-21_17h30_24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100572/4fe40cc3-7c5c-9e7f-d346-98c2aa6e3ce5.png)

架電 <- sum(IF(架電状況="完了",3,1))
ScatterElementsだけ動かすモデルをOnnx Runtimeを使って作成する

# ScatterElementsだけ動かして試す

## やりたいこと

- ScatterElementsの動作の理解のため、ONNXの仕様書に書かれていることを再現できるパイソンスクリプトを作成する事
- ONNX runtimeの使い方を理解する事 (オペレータを1つだけ使って、計算を行うグラフを作成し、ONNXファイルを出力する)

https://github.com/onnx/onnx/blob/main/docs/Operators.md#ScatterElements
```
data = [
    [0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0],
    [0.0, 0.0, 0.0],
]
indices = [
    [1, 0, 2],
    [0, 2, 1],
]
updates = [
    [1.0, 1.1, 1.2],
    [2.0, 2.1, 2.2],
]
output = [
    [2.0, 1.1, 0.0]
    [1.0, 0.0, 2.2]
    [0.0, 2.1, 1.2]
]
```

## 作成したスクリプト

```
import numpy as np
import onnx
import onnxruntime

#### input ####
data = np.array([
	[0.0, 0.0, 0.0],
	[0.0, 0.0, 0.0],
	[0.0, 0.0, 0.0],
], dtype=np.float32)

indices = np.array([
	[1, 0, 2],
	[0, 2, 1],
])

updates = np.array([
	[1.0, 1.1, 1.2],
	[2.0, 2.1, 2.2],
], dtype=np.float32)

#### output(のshape) ####
data_out = np.array([
	[0.0, 0.0, 0.0],
	[0.0, 0.0, 0.0],
	[0.0, 0.0, 0.0],
])

#### Attributes ####
axis = 0

#### graphの作成 ####
nodes = [
	onnx.helper.make_node(
		"ScatterElements",
		inputs=["data", "indices", "updates"],
		outputs=["data_out"],
		axis=axis,
		reduction="add", # add, max...
		)
]
print("\n=== nodes ===:\n", nodes)

inputs = [
	# make_tensor_value_info (name, elem_type, shape).
	# テンソルの型情報をテンソルのshapeとデータ型から作成する。
    onnx.helper.make_tensor_value_info("data", onnx.TensorProto.FLOAT, data.shape),
    onnx.helper.make_tensor_value_info("indices", onnx.TensorProto.INT64, indices.shape),
    onnx.helper.make_tensor_value_info("updates", onnx.TensorProto.FLOAT, updates.shape),
]
print("\n=== inputs ===:\n", inputs)

outputs = [
	# テンソルの型情報をテンソルのshapeとデータ型から作成する。
    onnx.helper.make_tensor_value_info("data_out", onnx.TensorProto.FLOAT, data_out.shape),
]

graph = onnx.helper.make_graph(nodes, "graph", inputs, outputs)
model = onnx.helper.make_model(
    graph, ir_version=9, opset_imports=[onnx.helper.make_operatorsetid("", 19)]
)
print("\n=== outputs ===:\n", outputs)

onnx.save(model, "test.onnx")

#### 計算の実行 ####
print(model.SerializeToString())
ses = onnxruntime.InferenceSession(
    model.SerializeToString(), providers=["CPUExecutionProvider"]
)

outputs = ses.run(None, {"data": data, "indices": indices, "updates": updates})
print(outputs)
```

## 実行結果

https://github.com/onnx/onnx/blob/main/docs/Operators.md#ScatterElements
に書かれている通りのoutputを得ることができた。

```
  :
[array([[2. , 1.1, 0. ],
       [1. , 0. , 2.2],
       [0. , 2.1, 1.2]], dtype=float32)]
(base) mozaki@yoshitsune:~/004_HDD/001_CODE/python_study/003_add$ 
```
AWS の Reachability Analyzer の分析結果は120日で消える

# 主旨

タイトル通り。

[この記事](https://docs.aws.amazon.com/ja_jp/vpc/latest/reachability/how-reachability-analyzer-works.html)に書いてあったがここに辿り着くまでに時間がかかったのでメモとして残しておく。

> Reachability Analyzer automatically deletes an analysis 120 days after its creation date.

Reachability Analyzer の結果を何らかの証跡に用いたりする場合、画面スナップショット取るなりしておいた方が良い。
結局Unityのモバイルアプリはどう計測したらいいんですか？（途中で力尽きたポエム）

# はじめに
Unityでモバイルアプリの性能を測ることになりまして、調査しながら計測をやってみたら色々罠を踏みました。
その結果をまとめました。誰かナレッジ作って。ないですか。じゃあ一通りまとめます。
技術情報はありますが、普遍的な内容にまとめられなかったのでポエム扱いです。

# ことのあらまし
- とあるUnity製のモバイルアプリがあります。
- 結構重い。
- じゃあ、アプローチとしてグラフィックを軽くしてみましょうか。
- UnityのProfilerで計測しましょうねー。
    - せっかくだから実機でチェックしよう！
    - Macも持ってるからiOSとAndroid両方チェックできるな！
    - USAGEでGPUがどれくらい変化したか取ったらいいっしょ！

# 結果
- うわー！ほしい情報が取れない…
    - **PROFILERのUSAGEで出てほしいのに！**
- 結局目論見通りに軽くなったのかわからない！
- **相手に説明できない！！**

# どうすればよかったか？
- まずはPCのUnityエディタ上で測ろう
- 何がボトルネックになるか、それを見極める
    - FPSやUSAGEだけが全てじゃない
- グラフィックはGPUのみならず
    - CPUも使うよね。
    - 当然メモリもVRAMだけでなく、通常のメモリを消費する。
    - ということは、描画に使われるメソッドがあるということ。
        - そこの動作時間がいつでも測れる。
- 記録はしっかりと残そう

# 具体的には何をして、何を間違え、何が起こったか？
- とりあえずFPSを指標にした
    - 重いのが課題のはずなのに、計測してるところが軽すぎてFPSがカンストしちゃう
    - 60FPS制限があってそれ以上にはあげられない（Android)
    - iOS（調べる。たぶん60FPS以上出る？）
- GPU Profilerがモバイルに対応していない
    - この世にNVidia Graphicsに対応している携帯端末ってNintendo Switchですよ（未確認）
    - ので、サードパーティーのプロファイラーやツールを当たる
        - GPUメーカーが提供しているProfilerアプリが
            - 検証機がSnapDragonだったのでQuallcomのSnapdragon Profilerを使用。
             ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75653/cf21ce9e-8703-db03-4fcf-83169ddca4e2.png)
                - スナップショットを取るとアプリケーションがクラッシュする…原因わからず。不採用。
    - iOSはiOSでXCodeで取得するのがベストプラクティス…だけど
        - フレームデバッガーと同等の内容が取れるけどわかりやすい数値としては取得できない
        - 情報の陳腐化が早すぎてGUIも変われば取得できるデータもコロコロ変わる
        - 過去のナレッジが役に立たない筆頭
        - どうすりゃいいんだこれ
# 結論
結局何を基準にしたらいいんだろうね。全くわからんよ。
なお、この記事2年前くらいに作ってて途中で塩漬けにしてたのですが、いまだに挽回できていないので悲しみを込めて公開します。なんとかなってますように。
ターミナルへのコピペで勝手に"\"が追加されて困ったときに読む記事

この記事はZOZO Advent Calendar 2023 #8 21日目の記事になります💁‍♂️

## この記事で解決できること
ターミナル(iTerm, VScodeのターミナルも同様)にコピペしたときに**勝手に" \ "が追加されてしまう問題を追加されないように修正し、解決**していきます。

文字だけだとわかりづらいと思うので、このような現象です👇
```zsh
- コピペ前
http://www.weather-from-the-future.com/forecast?date=2080-01-01&location=MoonBase

- コピペ後
http://www.weather-from-the-future.com/forecast\?date\=
2080-01-01\&location\=MoonBase
```

コピペ前とコピペ後で**何が変わったのかというと"?", "&", "="の前に" \ "が追加されてしまっています...**

この" \ "が勝手に追加されないように修正していきます👨‍💻

## 環境
- macOS Ventura13.6.2
- zsh 5.9
- oh-my-zsh

## 解決方法
さっそく、解決方法を書きます!!

"oh my zsh"関係のファイルが原因なので修正します。修正すると行っても、**下記ファイル(misc.zsh)の中身を数行コメントアウトするのみで解決**します🙌

```~/.oh-my-zsh/lib/misc.zsh
# *-magic is known buggy in some versions; disable if so
if [[ $DISABLE_MAGIC_FUNCTIONS != true ]]; then
  for d in $fpath; do
    if [[ -e "$d/url-quote-magic" ]]; then
      if is-at-least 5.1; then
        # autoload -Uz bracketed-paste-magic
        # zle -N bracketed-paste bracketed-paste-magic
      fi
      # autoload -Uz url-quote-magic
      # zle -N self-insert url-quote-magic
    break
    fi
  done
fi
```

おつかれさまでした🎉 これで修正は完了です!!

### (余談)なぜこの記事を書こうと思ったのか
修正自体は簡単です!!

しかし、日本語の記事を見つけることができず、英語の記事を呼んで解決したので少々時間がかかりました... 同士のためになればと思い書くことにしました👏

参考URL：https://github.com/ohmyzsh/ohmyzsh/issues/5569#issuecomment-453144639

## 原因
原因は、"oh my zsh"関係のファイルの設定でターミナルにコピペした特殊文字がエスケープシーケンスされてしまうところにありました。

今回の記事はここまで!! 良きzshライフを~~💁‍♂️

<details><summary>[おまけ] GPT先生に"エスケープシーケンス"について聞いてみた</summary>

エスケープシーケンスは、プログラミングやコンピューティングにおいて、特殊文字やコントロール文字を表現するために使用される方法です。

具体的には、エスケープシーケンスは特定の文字の前にバックスラッシュ（\）を置くことで、その文字が通常持つ特別な意味や機能を無効化（エスケープ）し、文字をリテラル（そのままの意味）として扱います。

例えば、ターミナルやシェルでコピペする際に、? や & といった特殊文字がコマンドや引数の区切りとして解釈されるのを防ぐために、これらの文字の前にバックスラッシュが追加されることがあります。これにより、これらの文字を文字通りの意味で扱うことができます。

</details>
widgetのテキストを取得・出力・削除

PythonからGUIを構築・操作するための標準ライブラリであるTkinterで使用するWidgetのテキストデータの扱いについてのまとめです．

## 動作環境
- Python 3.12.0
- tkinter 8.6.12
- tkcalendar 1.6.1

## Widget
### 文字ラベル
文字ラベルは次のコマンドで設定できます．
```tkinter.Label(text="")``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/1576bc87-a0b3-23fc-1602-a0c3ac22f5e8.png)

Labelウィジェットのテキストデータの取得・出力・削除は下記の通りです．
```python
wLabel = tkinter.Label(self.main, text="test") #self.main...ウィンドウ
# テキストデータ取得
wLabel.cget("text")
# テキストデータ出力
wLabel["text"] = "Qiita"
# テキストデータ削除
wLabel["text"] = ""
```

### テキストボックス
テキストボックスは次のコマンドで設定できます．
```tkinter.Entry()``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/958b14c7-af6f-f2fc-237c-d16c6dfe808b.png)

Entryウィジェットのテキストデータの取得・出力・削除は下記の通りです．
```python
wEntry = tkinter.Entry(self.main) # self.main...ウィンドウ
# テキストデータ取得
wEntry.get()
# テキストデータ出力
wEntry.insert(0, "Qiita")
# テキストデータ削除
wEntry.delete(0, tkinter.END)
```
```insert```と```delete```の第一引数は，何文字目から出力，削除を行うかを設定できます．上記の例では，0文字目（頭）からQiitaの文字列を出力，0文字目（頭）から最後の文字まで削除を行っています．

### スクロールテキストボックス
スクロールテキストボックスは次のコマンドで設定できます．
```tkinter.scrolledtext.ScrolledText()``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/eb912399-7105-4355-6153-aa0c8674a54c.png)
右端を見るとうっすらスクロールバーが見えます．

ScrolledTextウィジェットのテキストデータの取得・出力・削除は下記の通りです．
```python
wScrolledText = tkinter.scrolledtext.ScrolledText(self.main) # self.main...ウィンドウ
# テキストデータ取得
wScrolledText.get("1.0", "end-1c")
# テキストデータ出力
wScrolledText.insert(0, "Qiita")
# テキストデータ削除
wScrolledText.delete('1.0', 'end-1c')
```

### プルダウン
プルダウンは次のコマンドで設定できます．
```tkinter.ttk.combobox()``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/97a01da6-96b1-3b39-d86d-79a674814328.png)

comboboxウィジェットのテキストデータの取得・出力・削除は下記の通りです．
```python
lst = ("0", "1", "2")
wCombobox = tkinter.ttk.combobox(self.main, values=lst) # self.main...ウィンドウ， values...選択リスト
# テキストデータ取得
wCombobox.get()
# テキストデータ出力
wCombobox.set("Qiita") # 文字列がリストになくても表示できます．
# テキストデータ削除
wCombobox.set("")
```

### チェックボックス
チェックボックスは次のコマンドで設定できます．
```tkinter.Checkbutton()``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/27a4fa3c-0fb2-bdbb-b064-e146df875617.png)

Checkbuttonウィジェットのテキストデータの取得・出力・削除は下記の通りです．
```python
boolvar = tkinter.BooleanVar() # True/False
wCheckbutton = tkinter.Checkbutton(self.main, variable=boolvar) # self.main...ウィンドウ
# チェック状態取得
boolvar.get() # 取得値はTrue/False
# チェック状態を設定
boolvar.set(True) # チェックをつける
boolvar.set(False) # チェックを外す
```

### カレンダー
```tkcalendar```という外部ライブラリになりますが，カレンダーは次のコマンドで設定できます．
```tkcalendar.DateEntry()``` 絵 ↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3617469/aecba9aa-cef7-c709-0972-d3feaa3fb419.png)

DateEntryウィジェットの日付データの取得・出力は下記の通りです．
```python
wDateEntry = tkcalendar.DateEntry(self.main) # self.main...ウィンドウ
# 日付を設定
wDateEntry.set_date(date) # dateはDate型変数 
# 日付を取得
wDateEntry.get_date() # 取得値はDate型
```
jsの基本アウトプット

#    比較演算子について
一覧
| 比較演算子  |内容                                 |
|:-----------|:------------------------------------|
| A == B 　  | AとBは等しい。AとBは一緒。            |
| A != B     | AとBは等しくない。AとBは一緒ではない。|
| A < B      | AはBより小さい。                     |
| A <= B     | AはBと等しいかそれより小さい。        |
| A > B      | AはBより大きい。                     |
| A >= B     | AはBと等しいかそれより大きい。        |

#    switch文
サンプル
```ruby:switch文
var month = 12; 
var season;

switch (month) {
  case 1: season = '冬'; break;
  case 2: season = '冬'; break;
  case 3: season = '春'; break;
  case 4: season = '春'; break;
  case 5: season = '春'; break;
  case 6: season = '夏'; break;
  case 7: season = '夏'; break;
  case 8: season = '夏'; break;
  case 9: season = '秋'; break;
  case 10: season = '秋'; break;
  case 11: season = '秋'; break;
  case 12: season = '冬'; break;
  default: season = '???';
}
document.write('<p>' + month + '月は、' + season + 'です。');
```

#    while文、for文について
まず初めに

:::note warn
「無限ループ」に注意する
ずっと繰り返し続ける条件を設定した場合「無限ループ」が起こります。
内容はその名の通り無限にループすることです。無限ループが起こると暴走状態になり、落ちます。条件を設定する際は必ず抜ける条件も設定しましょう。
:::

###  基本形
```ruby:whileの基本形
while ( 条件 ){
    処理
}
```


```ruby:forの基本形
for ( 初期値 ; 条件 ; 後処理 ){
    処理
}
```
一ヶ月間Qiitaに毎日投稿した結果「アドベントカレンダー皆勤賞 （完走した感想）」

# はじめに
はじめまして。えか太郎と申します。アウトプットが少ない（ゼロ）と言うのはいささか問題だと思ったので１２月は毎日記事投稿するという目標を掲げこの一ヶ月間頑張ってきました。見事一ヶ月毎日投稿できた（＃注）のでそれによって得たモノについて共有したいと思い本記事を執筆しています。
### ＃注
毎日投稿できたと書いておりますが正確にはアドカレに毎日投稿できただけであって、毎日記事を書いたわけでも余裕を持ってストックを作り、その日ごとに投稿できたわけではありません。現にこの記事を書いている現在、あと８記事かかないと２５記事になりません。今夜は寝かしてくれなさそうです。
# 感想
メリットとデメリットを上げたいと思います。
## メリット
### 何もせずにだらける日が減った
毎日何かしら活動しないと後半がつらくなるのでダラダラする日が激減しました。毎日が（忙しすぎて）
### マークダウン記法が身についた
マークダウンでメモを取ったり、プレゼンテーションのプロットをかけるようになるのはすごく便利です。義務教育で教えてほしい。
### 簡潔な書き方が少し身についた
人に読まれるものを書くのって難しいんだと痛感しました。これまで読むばかりでしたので。実際に書く側に立ってこそ得られる学びっていうやつがあった気がします。

## デメリット
### 毎日投稿はネタ切れと質の低下を招く
普通に考えてみればわかることです。高校生にそんな大層なネタがたくさんあるわけありませんでした。ひねり出しましたが。もうしたくないことよ（詠嘆）
### 記事を書くのにかなり時間がかる
これも普通に考えてみればわかることでした。「記事執筆」＋「記事に書く内容を実行する」だけで最低でも２、３時間かかりました。不慣れなのもあったとはいえかなり生活が忙しくなってしまいます。
# 皆勤賞について
私が一ヶ月毎日投稿できたのはQiitaの皆勤賞があったから他なりません。やはり何かモチベーションになるものがないとおそらく一日で終わっていたと思います。ちなみに皆勤賞ではQiitaのぬいぐるみとTシャツがもらえるらしいです。やったね。
![スクリーンショット (37).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3120367/fda1ee07-41a1-74d3-aeba-11688754afa0.png)
# おわりに
一ヶ月毎日投稿をするのではなく２ヶ月で３０記事みたいにしないと、質の低い記事を量産するだけになるので真似はおすすめしません。しかし、意識は多少は高まるので自身の怠惰さをなんとかしたい人は一考の価値があるかもしれません。プログラマー３大美徳の一つですが...
これからもちょくちょく駄文を書きますのでよろしくお願いします。
メモ C# lock を使用した珍しい不具合 

TCP/IP使用したサーバー側のソケット通信にて複数のクライアントからデータに対してアクセスが行われる為、下記のような、lockを行い排他制御を行った。
下記コードが最適では、無かったが、その際に遭遇したlockの動作についてメモする

ReceiveCallBackを再起動後にLogを出力するコードを記載していた
```C#:Sample.cs

        private static object lockReceiveCallBack = new object();
        
        void ReceiveCallBack(IAsyncResult ar)
        {
            lock (lockReceiveCallBack)
            {
                // 受信処理
                LogOut("ReceiveCallBack Start");

                // 再起動
                clientSocket.BeginReceive(dataBuffer, 0, 1024, SocketFlags.None, ReceiveCallBack, clientSocket);
                        });
                LogOut("ReceiveCallBack End");
            }
            
        }
```

同じクライアントから通信が連続してあった場合、実行したLogの結果が、以下になる
```Log:result.txt
ReceiveCallBack Start
ReceiveCallBack Start
ReceiveCallBack Start
ReceiveCallBack End
ReceiveCallBack End
ReceiveCallBack End
```
想定では以下になる
```Log:result.txt
ReceiveCallBack Start
ReceiveCallBack End
ReceiveCallBack Start
ReceiveCallBack End
ReceiveCallBack Start
ReceiveCallBack End
```
「ReceiveCallBack End」が実行される前に次の受信イベントが発生し、ReceiveCallBackに再入して処理が行われて、「ReceiveCallBack End」のLog出力が後回しになっている。
lockを実行している為、再入はできないと考えていたが、想定とは違う結果になった。同じスレッドという認識で動作しているのか、それとも別の原因か
原因究明は、できなかったが、lockの使用をやめたら解決した
何れにしろ、lockを実行する範囲は限定的にする必要がある
Flutterのdart:ffiでOpenCvを使う

# はじめに
FlutterでOpenCvを使いたかった。
pub.devで一部のOpenCv機能が使えるLibがあるが、2023.12時点ではMatレベルで操作できるものは存在しなかった。
仕方がないので、公式SDKをDLしてdart:ffiとC++を使ってOpenCvおよびMatを操作できるようにする。
ざっくりとしたコードの依存は dart:ffi -> cpp -> OpenCvSdk となり、言語はdartとcppで完結する。

公式SDK
https://opencv.org/releases/

# iOS

iOSでOpenCv

https://levelup.gitconnected.com/building-a-flutter-computer-vision-app-using-dart-ffi-opencv-and-tensorflow-part-1-513dac9325ab

Mat受け渡しが上記そのままではだめなので、その対応方法

https://stackoverflow.com/questions/72490616/processing-flutter-images-with-c-opencv


# Android

AndroidでのSDK取り込み方法が記されている。
LinuxとWinについても言及されているが、筆者には不要なため試していない。
VsCodeが推奨されているが、AndroidStudioでも問題なく適用できた。
わかりやすい具体的な方法が記述されており、調査の手間を考えると有料分の価値はあった。

https://techbookfest.org/product/1VEBJHbmVmb8D6eFvcE5VF?productVariantID=6MFqp6aV5cY8B3tzpUNi35


# 感想
先人に感謝。
FlutterでMatが簡単に使えるように、pub.devで誰か対応してくれたら助かる。
各SDKの使い方はOpenCv公式がもうちょっと親切に解説してほしい。
【個人開発】工数登録システムを作ってほんの少し業務効率化した話

# はじめに
この記事は2023年度の振り返りです。

今回は、以前の記事を経て作った「工数登録システム」の紹介となります

https://qiita.com/youfuku/items/30c444d5330ab0f7cf5b

https://qiita.com/youfuku/items/66022716201f11924efb

# 工数登録システムとは
毎日の業務(工数)を登録していたりするのですが、登録するのが面倒だったりで貯めて登録することが多々ありましたので、それを改善するためのアプリです

以下の機能があります

### 機能1：スケジュール通知
![l_6814799_93_b6759ac4701521b0b3d38588168e9f1e.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/2b512795-52e4-cf1b-0e5e-c389b9acf163.png)

グループウェアのスケジュールをスクレイプしDBに保存。
それをFullCalendarで表示しています。
スケジュール忘れ防止として、時間が近づくとlineで通知するなどしています

### 機能2：スケジュールをredmine登録
![l_6814799_94_a04926434774fb54caea35280fa65b3a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3632357/a8503461-47c7-b0a6-d727-35f6ae77280d.png)
自分たちは、行った作業を全てredmineに記録しています。
ただ、毎日実施するものに対しては、少しでも楽をしたいと思い、ボタン一つでredmineに記録できるようにしました。(もちろん削除も可能です)
ほんの1分にも満たない作業効率ではありますが楽になったのは確かです

### 機能3：redmine登録済みを提出用システムに自動入力
redmineに記載れた作業工数を提出用システムに記載していますが、これがなかなか面倒でした。
1日分を入力するだけでも5分くらいかかっていました。
このシステムを使えば、ボタン一つで予約され、スクレイプの要領で自動で入力してくれます。

# さいごに
業務効率化を目指し、細々と開発をしていました。
今年になって提供を始め、利用者からは高評価を頂いております。
利用者が楽になるという価値が提供できたの個人的には成功だと思っています。
今後もこんなツールを作っていきたいと思った次第でした。
CSSを完全に理解したかった

# はじめに
社員旅行のホテル着としてネタでよく見る枠線からはみ出た**CSS理解したTシャツ**を買いました。
その時に、あれこれって実は何も考えずに書けなくない・・・？ってなったので書いてみました

# チャレンジ１
基本的にdivとかで囲った中に文字打って幅指定しても折り返されて終わるよな・・・？
ってことで試しました。

```html:test.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>CSSを完全に理解したかった</title>
	<style>
		.box {
			border: thick double #000000;
			width: 300px
		}
	</style>
</head>
<body>
	<div class="box">
		<h1>CSS<br>完全に理解したかった</h1>
	</div>
</body>
</html>

```
## 結果
まぁそうなるよねっていう感じで予想通りダメでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519878/9e9e173b-1f0b-1fa9-2efd-29cf6f859648.png)



# チャレンジ２
折り返し禁止にしたらはみ出してくれるんじゃないかってことで

```html:test.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>CSSを完全に理解したかった</title>
	<style>
		.box {
			border: thick double #000000;
			width: 300px;
			white-space: nowrap;
		}
	</style>
</head>
<body>
	<div class="box">
		<h1>CSS<br>完全に理解したかった</h1>
	</div>
</body>
</html>

```

## 結果
予想通りいい感じに

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519878/38696046-f98e-3b1c-a758-90dd98ee08c8.png)


# 見栄えをもうちょっとオリジナルに寄せたい
よく見るやつだと文字の始まりがもっと右かつ枠線がもうちょい丸みを帯びているので
それに合わせられるように少し追記した

```html:test.html
<!DOCTYPE html>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>CSSを完全に理解したかった</title>
	<style>
		.box {
			border: thick double #000000;
			width: 300px;
			white-space: nowrap;
			border-radius: 20px;
		}
		h1 {
			margin-left: 50px;
		}
	</style>
</head>
<body>
	<div class="box">
		<h1>CSS<br>完全に理解したかった</h1>
	</div>
</body>
</html>

```

## 結果
持ってるTシャツとほぼ同じデザインになったのでハッピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519878/133a905d-3962-3ed6-674a-2083d301190d.png)


# おわりに
CSSあんまり理解してないけど初歩的な知識で書けるもんだなぁってなりました。
CSS理解したシリーズのミームはいろいろあるのでミーム再現で書いてたら実際に理解進むかもしれないので今後もやってみようと思いました。
GitHub Actionsを使ってPR時に自動でreviewersアサインと担当者アサインをする

# はじめに
GitLab時には、MRテンプレートにて、reviewersアサインをしていました。

やり方はいたくシンプルで、

```.gitlab/merge_request_templates/default_template.md
.....


/assign_reviewer @hogehogehogehogehogehogehogehogeho
```
とユーザー名を指定するだけです。

ですが、GitHubではPRテンプレートに指定をすることができません。
調査した結果、GitHub Actionsでのやり方が判明したので、ここにメモ書きします。

# やり方
こちらが参考になりました。

https://qiita.com/sii_gizmo/items/b70a83b46a4895e6f7e8

エラーが出たので少し手直ししました。
他に、専用ボットがあるのでそれを使っても良いと思います。

https://github.com/apps/auto-assign

私は、github actionsを使いました。
理由としては、pull request時の条件文を少し変更したかったのと、初めてのactionsなので触ってみたかったことです。

## とりあえず、コードを見ちゃおう
設定ファイルはymlで書きます。
```.github/workflows/hogehoge.yml
# レビュワーの自動アサイン
name: auto-assign
on:
  pull_request:
    # どんなときに実行するか
    types: [opened, ready_for_review, reopened]
jobs:
  add-reviews:
    runs-on: ubuntu-latest
    # Actionsが必要とするpermissions
    permissions:
      pull-requests: write
      contents: read
    steps:
      # Node.js関連のエラーが出た。バージョン上げた。
      - uses: kentaro-m/auto-assign-action@v1.2.5
        with:
          repo-token: "${{ secrets.GITHUB_TOKEN }}"
          configuration-path: ".github/auto_assign.yml" # 呼び出し
```

```.github/auto_assign.yml

# Set to true to add reviewers to pull requests
addReviewers: true

# PR出した人を担当者にする
addAssignees: author

# PRのreviewersを指定
reviewers:
  - hogeo1
  - hogeo2
  - hogeo3

# A number of reviewers added to the pull request
# Set 0 to add all the reviewers (default: 0)
numberOfReviewers: 0
```

これらを配置すると、PRを出したときに、自動で動いてくれます。
Slackと連携していれば、通知時にメンションもされます。非常に便利です。

## トラブルシューティング
![スクリーンショット 2023-12-20 14.03.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1026740/de0f39f4-57e6-040f-974d-12b65ff58257.png)

エラーが3つ出ました。

### The following actions uses node12 which is deprecated and will be forced to run on node16: kentaro-m/auto-assign-action@v1.1.0. For more info: https://github.blog/changelog/2023-06-13-github-actions-all-actions-will-run-on-node16-instead-of-node12-by-default/

Node.jsのバージョンが古いから、適用する`kentaro-m/auto-assign-action@v1.1.0.`のバージョンを上げてくれ　ということだそうです。あげたところエラーは消えました。
ちなみに、chatgptに聞いたら即解決。

```yml
# Node.js関連のエラーが出た。バージョン上げた。
      - uses: kentaro-m/auto-assign-action@v1.2.5
```

### Warning: Resource not accessible by integration
これはGitHub Actionsではよくあるエラーらしいです。
権限回りのエラーとのこと。

調べたところ、repositoryのsettingsにあるActionsの権限を`read and write permissions`にすれば良い、という情報も出てきたのですが、ここで権限をいじるのはあまり良くないようです。

pull requests時の権限をread, writeにするだとかそういう権限設定が必要です。
今回は、pull requestsおよびcontentsの権限をactionsのymlに記載しました。

```yml
    # Actionsが必要とするpermissions
    permissions:
      pull-requests: write
      contents: read
```

詳細は以下のページで確認できます。

https://docs.github.com/ja/actions/using-jobs/assigning-permissions-to-jobs
LINE WORKSの気づきにくい設定

LINE WORKSの中には、APIで使える特殊な設定があります。

# 1.利用ブラウザの変更
通常、LINE WORKSで共有されたURLはアプリ内ブラウザで表示されます。
しかし、webサービスによってはユーザー認証の都合や、特定のセキュアブラウザからのアクセスのみを許可している場合もあるかと思います。
アプリ内ブラウザで一度開いた後に標準ブラウザで開き直しても良いのですが、スムーズな遷移を望む方のためにブラウザ指定を変更するAPIがあります。

### Security API
https://developers.worksmobile.com/jp/docs/security

注意点として、設定はテナント全体に一律に適用されます。
(特定のユーザーだけ例外扱いにはできません。)

# 2.カスタムフィールド
https://developers.worksmobile.com/jp/docs/directory-customer-field-create

アドレス帳に社員番号や内線番号、他システムのプロフィールページへのリンクなど情報を付与したいことがあります。
LINE WORKS の管理画面GUIではフィールド項目は固定ですが、Directory APIではカスタムフィールドを追加できます。
- フィールド数はドメイン内で5個まで
- 入力形式はテキスト(STRING)もしくはURL形式の選択
- アプリごとのアドレス帳への表示の有無も選択可能　(システム連携用のパラメータをメンバーに意識させないで登録しておくこともできる)

なお、管理画面のGUI上でもフィールドと値が表示されますが、値の指定や更新はAPI経由でのみ行えます。

# メンバー即時削除
LINE WORKSでは、管理者の誤操作を防止するため、メンバーを削除しても7日間は削除待ちの状態で維持されます。
登録ミスでIDをすぐに再利用したい場合など、管理画面ではメンバーを削除 → 削除済みユーザーを選んで「完全に削除」という2ステップの操作が必要になります。
こちらのAPIを使うと、1回の操作でメンバーを完全に削除できるためテスト時のユーザー操作の確認等に便利です。

### ユーザー(メンバー)の即時削除
https://developers.worksmobile.com/jp/docs/user-force-delete

以上、小ネタでした。
初めての3Dプリンター 印刷編

## 環境
Mac 12.3.1
(多分、Windowsの方もほぼ一緒です）
## 利用ソフト
Autodesk Fusioon360
FlashPrint 5

## 印刷手順
[初めての3Dプリンター　モデル作成方法](https://qiita.com/sandream/items/d30325b50cc8a41690f2)　で作成したモデルを印刷します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/3183e94e-f478-832d-e5c9-d5c340ec0075.png)


1:ファイルからエクスポートを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/10554311-d67f-a2b2-00f9-ee3d23ae031b.png)

2:名前を任意の名前にし、タイプをSTLファイル(*.stl)を選択。場所も任意の場所を指定しまし
エクスポートボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/cbafe6bc-447b-2c5b-dc66-cc1b87743ab5.png)

3:ジョブステータスが表示され、ステータスが完了になれば、保存した場所にファイルができています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/a433757c-f296-8eb3-21ff-678f4379fa7d.png)

4:FlackPrint5を起動　ファイルからロードファイルを選択し開く
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/18daccb2-d78c-25eb-a09c-08eb866cfc27.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/95a3af18-773e-9dd0-da8e-eab4c9f69e89.png)

5:スライスを実行ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/fbf4f8a9-9400-f321-8ab2-2328dc1efa42.png)

6：プリント設定を行う
今回は、プリンタがAdventurer 3Xを利用するので、　プリンタの種類は Adventurer 3 Seriesを選択。
ノズル径や樹脂の種類も利用するものに合わせる。今回は、Flashforge-PLA 1.75mm。
スライスプロファイル　標準　と　細かい　速いが選択できます。
細かいにすると、時間がかかるそうです　速いにすると早くはなりますが、印刷失敗するケースも多いそうです。
今回は、標準で印刷します。
設定できたら　スライスボタンをクリック。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/4362a204-c987-c000-4a45-1a70301ad4a0.png)

7:プリンタに送信ボタンを選択すると、同じWi-Fi環境にいるプリンターが表示されます。
（IPアドレスで指定することも可能です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/ecfc36e1-1b3f-2fa9-8ceb-e69b03ced762.png)

8:ファイル名を聞かれるので、任意の名前を設定（変更しなくてもOK）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100769/1d10023d-00b6-207e-0439-4003c1d47869.png)

9:印刷が始まります


印刷が始まったら、樹脂がちゃんと出ているかなど確認して問題なければ、時間までゆっくり待ちましょう。
経験者の方や、さまざまな情報を見ると、失敗して謎の糸の塊のようなものが生成される場合もあるようですが、
それはそれで、ネタとして楽しみましょう!!



#### 関連リンク
[初めての3Dプリンター インストール編](https://qiita.com/sandream/items/b32ea55b9e8531db5a3a)
[初めての3Dプリンター モデル作成方法](https://qiita.com/sandream/items/d30325b50cc8a41690f2)
[初めての3Dプリンター 印刷編](https://qiita.com/sandream/items/c11e0c1adfb6c98e837e)
エクセル方眼紙の魅力

あえてエクセル方眼紙の設計書の魅力を語る。
裏返せば以下のツールとしての強みをひっくり返さないとなかなかエクセル方眼紙設計書を追い出すことはできない。

- 方眼紙シートでお絵かき、別シートでデータそのものが１ファイルに入る
    - エクセル方眼紙を書いてる人もそれがデータとして役に立たないことくらいわかってる
- 1ページに収まる
    - ページの概念なしにいろいろ描いた結果、1ページに収めることができる
    - これが超便利。代替ツールはFingaとか
    - ペタペタスクショはって印刷時に一枚に収めるアプリで他にいいのがない
- １セルに収まる
    - 文字がセルを溢れるときに文字を自動的に縮小する機能がある
    - 印刷を考えると超便利
    - フォントが置換されても溢れないという最強の機能
- マウス要らず
    - セルの罫線だけで、ちょとしたワイヤーは描ける
    - しょぼいノートPCでも画面開発ディレクションができる
- リンク埋込ができる
    - 表データをオートシェイプのように埋め込むことができる
    - 20年前から存在する機能。超便利。
- エクセルがインストールされたWindowsはめちゃくちゃ多い
    - 方眼紙が読み書きできるPCはめちゃくちゃ多い
    - 他のどのお絵描きアプリよりも多い
GCPのGPU搭載インスタンスで [Errno 13] Permission denied: '/root/google_vm_config.lock'

# 背景
GCPのGCEのGPU搭載インスタンスで推論処理の入ったunicornプロセスを起動したところ `[Errno 13] Permission denied: '/root/google_vm_config.lock'` のエラーが発生

# 環境
- Debian GNU/Linux 11
- cuda 11.8
- bitsandbytes 40.2

# やったこと

`GOOGLE_VM_CONFIG_LOCK_FILE` を `.../bitsandbytes/cuda_setup/env_vars.py` の to_be_ignoredn追記する

### 参考
https://github.com/TimDettmers/bitsandbytes/issues/620#issuecomment-1666014197

私の環境では、env_vars.pyは以下のpathでした `/home/USER_NAME/.local/share/virtualenvs/VIRTUAL_ENV/lib/python3.10/site-packages/bitsandbytes/cuda_setup/env_vars.py`


```py
from typing import Dict


def to_be_ignored(env_var: str, value: str) -> bool:
    ignorable = {
        "PWD",  # PWD: this is how the shell keeps track of the current working dir
        "OLDPWD",
        "SSH_AUTH_SOCK",  # SSH stuff, therefore unrelated
        "SSH_TTY",
        "HOME",  # Linux shell default
        "TMUX",  # Terminal Multiplexer
        "XDG_DATA_DIRS",  # XDG: Desktop environment stuff
        "XDG_GREETER_DATA_DIR",  # XDG: Desktop environment stuff
        "XDG_RUNTIME_DIR",
        "MAIL",  # something related to emails
        "SHELL",  # binary for currently invoked shell
        "DBUS_SESSION_BUS_ADDRESS",  # hardware related
        "PATH",  # this is for finding binaries, not libraries
        "LESSOPEN",  # related to the `less` command
        "LESSCLOSE",
        "_",  # current Python interpreter,
        "GOOGLE_VM_CONFIG_LOCK_FILE" # ←追記
    }
    return env_var in ignorable


def might_contain_a_path(candidate: str) -> bool:
    return "/" in candidate

~略~
```
Pythonのコーディングスタイルの統一と静的解析について

# 概要

Pythonを使ったプロジェクトでコーディングスタイルや規約の属人化を抑制するためのツール群について解説します。 VSCodeの拡張機能として使うことを前提とします。

:::note info
※ 私が株式会社愛宕 Advent Calendar 2023に書く記事は主に社内向けに共有しておきたいけど勉強会をするまでもないちょっとしたTipsにしたいと思います。
:::

# やりたいこと

- コーディングスタイルの統一
    - 空白の入れ方や改行の位置や一行の行数などを全てのソースコードで統一して読みやすくすること
- コーディング規約の順守
    - ソースコードレビューでコーディング規約違反を指摘するのは面倒なので規約が守られているかどうかを機械的にチェックすること
    - コーディング規約は最も費用対効果の高い品質向上施策と言われています
- 静的解析
    - Pythonにはコンパイルがないため実行時にならないとバグが発見できません。しかし、一部のバグは想定している型の違いに起因することが多いため、コードに型ヒントを記述しそれが矛盾がないかどうかをチェックすること
    - セキュリティ的に脆弱性になりやすいコードの書き方を解析し問題を早期発見すること

# やりかた

## コーディングスタイルの統一

一般的にコーディングスタイルを統一するにはフォーマッター(formatter)を使用します。フォーマッターは決められた形式になるようにソースコードを整形します。

Pythonのフォーマッターで有名なものでVSCodeから利用できるのは次の3つです。 全てpipでインストールしなければ使用できません。 

- autopep8: PEP8準拠のスタイルに整形してくれる
- yapf: Google謹製。PEP8準拠じゃなく良くも悪くもGoogleスタイル
- black: 細かい設定が一切できない。その代わり設定を考える必要がない

コーディングスタイルは好みが出る部分でこだわるプログラマなら一家言あるところですが、スタイルが統一されているならどんなものでも効果はあるので細かい設定ができないblackを選択するのが無駄な議論をする必要がなく最も費用対効果が高いと考えられます。

ファイルを保存したタイミングで自動で整形するようにVSCodeを設定すると捗ります。

### 設定例

blackの設定はコマンドライン引数でおこないます。

```sh
--line-length=99
```

この例では一行の文字数が99文字になります。

### インポート順の正規化

モジュールのインポート順は最適な順序が存在します。どんな言語でも通常は言語処理系に標準添付されているような基本的なモジュールを最初にインポートし、フレームワーク、プロジェクト内、ローカルディレクトリ内モジュールの順になります。

これをプログラマが判断しながら並び替えるのは無駄な労力なので自動で並び替えるツールが存在します。

Pythonではisortを利用します。VSCodeには標準添付されているので追加でインストールする必要はありません。 ただし、ファイル保存時に自動で並び変えるにはVSCodeの設定画面で「`settings.json`で編集」ボタンを押して編集する必要があります。

```json
"editor.codeActionsOnSave": { "source.organizeImports": true }
```

## 静的解析

一般的にコーディング規約をチェックするにはリンター(linter)を使用します。また、型チェックや脆弱性チェックなどの静的解析もリンターが行います。 リンターは規約に違反した箇所をerror, warning, infoなどのレベル別に指摘することができます。

なお、VSCodeのPython言語サーバー（標準PythonまたはPylance）も補完のために解析を行っているため問題が通知されることがあります。

Pythonのリンターとして有名なものの中でVSCodeから利用できるのは以下の通りです。 全てpipでインストールしなければ使用できません。 

- Pylint: VSCodeの標準のリンター
- Flake8: 関数の複雑さなども解析してくれる
- Bandit: パスワードの直書きなどのセキュリティ問題を検出してくれる
- Mypy: 型ヒントに従って型の整合性をチェックしてくれる
- Pycodestyle: スタイルがPEP8に従っているかどうかをチェックしてくれる
- Pydocstyle: ドキュメントのスタイルがPEP257に従っている稼働がをチェックしてくれる
- Pylama: Flake8のようなもの？未使用のため不明
- Prospector: Flake8のようなもの？未使用のため不明

総合的にはFlake8を利用するのが最適で加えてBanditでセキュリティ関連の解析とMypyで型のチェックを補助的に行うのがいいと思います。

ファイルを保存したタイミングで静的解析がかかるようにすると捗ります。

### 設定例

flake8の設定はコマンドライン引数でおこないます。

```sh
--max-line-length=99
--ignore=E203,W503,W504
```

この例では一行の文字数が99文字になります。blackで整形するスタイルが静的解析にかからないようにしています。 また、E203, W503, W504の問題を無視することにしています。

### 無視設定

静的解析は完璧ではないので全く問題のない箇所であっても指摘されることがあります。その場合は、リンターに無視させるための記述方法がそれぞれのリンターに存在します。

### Flake8

コメントに`noqa`と書いた行は無視されます。

### Bandit

コメントに`nosec`と書いた行は無視されます。
Playwrightで実際にPOSTされる値を観測する

```ts
import { test } from "@playwright/test";

test("実際にPOSTされたデータの中身が見たい", async ({ page }) => {

  // フォームを開く処理などを行う

  const requestPromise = page.waitForRequest(actionPath);

  // リクエストが来るのを待つ
  const requestPromise = page.waitForRequest(actionPath);

  // interceptして実際にはデータが飛ばないようにしておく
  page.route(actionPath, (route) => route.abort());

  // 登録ボタンのクリック
  await page
    .getByRole("link", { name: /^登録$/ })
    .first()
    .click();

  // リクエストを待機する
  const request = await requestPromise;

  // interceptを解除しておく
  page.unroute(actionPath);

  // requestを使ってPOSTされたデータを確認できる
  const json = request.postDataJson(); // request.postData(), request.postDataBuffer()もある
  const postData = JSON.parse(json);
  console.log(postData);

  // Assertなどを行う

});
```
クリーンアーキテクチャについての理解

# 概要
本記事はクリーンアーキテクチャについての自身の理解を表明する、みたいな記事ですので、本記事を参考にクリーンアーキテクチャについて学ぼうというのはあまりお勧めしません。

# クリーンアーキテクチャについて
開発のしやすさ、保守のしやすさ等、機能追加や機能修正といったことをよりやりやすく、安全にするためのシステム構造です。以下のことを提供しています。

- フレームワークに依存しないこと
- ビジネスルールはそれ単体でテストが実行可能であること
※ビジネスロジックと置き換えてもそう大差変わらない、と思う
- UIに依存しないこと
- データベースに依存しないこと
- 外部機関に依存しないこと

![スクリーンショット 2023-12-07 16.03.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3198267/be58589e-2018-c932-242c-bfcfce529228.png)
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

円の一番外側はWeb、Devices、DBといった、サーバとは分離された別サービスであり、その内はビジネスロジックたるUseCaseを扱う部分であるControllersで、その内はUseCasesです（最内のEntitiesはよくわかりません）。依存関係の向きを表す矢印が外から外から内へと伸びているように、このような依存関係を構築します。また、右下に小さく図示されているのは、UseCaseがControllerからのリクエストを受け入れること、UseCaseがデータをHTML、JSONに変換するPresenters（フロントエンドのフレームワークがやっていそうなこと？）に送ること、を示している。

# 実装でのクリーンアーキテクチャの使用
このクリーンアーキテクチャをどうやって真似るのかについて説明します。
登場人物を以下の通り。
- UseCase: 必要に応じてRepositoryから実装を拝借するビジネスロジックの実装部分
- Controller: 必要に応じてUseCaseから実装を拝借して何かしらのレスポンスをクライアントに返す部分
- Router: 外部との接続点とControllerを紐づける部分
- DB: データベース
- Repository: データベース処理を記述する部分

## 依存性の注入
説明に依存性の注入とやらを使用するので、これを先に説明しておきます。依存関係を外部からもらうことを依存性の注入と呼び、Constructor Injection（引数からインスタンスや関数をもらうアレ）がそれに該当します。
クリーンアーキテクチャ関係なしに何が嬉しいのかというと、依存関係を内部に持たないのでそれ単体で使いやすいということです。わかりやすいところで言うとモックを使えるというところです。引数で依存関係のあるインスタンスや関数を受け取るので、これをモックに置き換えることで単体テストが容易になります。また、モックだけでなく、その関数の要望に適しているものであればどんなインスタンスでも関数でも付け替えることができます。
この依存性の注入とインターフェース（UIではない）を使うことで依存関係をいじることができます。

## 依存方向の調整
では、いよいよクリーンアーキテクチャを真似る方法について説明します。
- UseCaseはControllerを使ってその機能を使用されます。例えばログイン機能がUseCaseにあって、これをControllerが使うという形です。これは何もしなくても良いところです。
- ControllerはRouterを使ってその機能を使用されます。例えばログイン機能がController（UseCaseの機能を拝借している）にあって、これをRouterが使うという形です。これも何もしなくても良いところです。
- DBはRepositoryを使ってその機能を使用されます。例えばデータ作成機能がDBにあって（Create）、これをRepositoryが使うという形です。これも同様です。
- RepositoryはUseCaseを使ってその機能を使用されます。例えばユーザ登録機能がRepositoryにあって、これをUseCaseが使うという形です。クリーンアーキテクチャでは、Gateway（Repository）はUseCaseに依存する構造ですが、使う側が依存する側、使われる側が依存される側ですので、依存の方向が違っています。ここを変えることが真似するということです。

## 依存方向の逆転
やり方は単純です。ただ、依存方向の逆転と書いてはいますが、さすがにRepositoryがUseCaseに依存する関係を作るのは困難です。ですので、インターフェースを使って依存方向をちょっと変えます。
具体的にはUseCase→Repositoryインターフェース←Repositoryという感じに変えます。インターフェースとは端的に言いますと、仮決めのRepositoryみたいなものです。これを使用することでUseCase側はこの仮決めのRepositoryに依存しますが、実際のRepositoryには依存しません。また、Repositoryは仮決めのRepositoryに依存します。

# おわりに
というわけでこんな感じです。最初に述べたようにクリーンアーキテクチャについてほとんど理解せずこのような記事をあげているわけですが、書いているうちに理解が深まったらいいな〜、という動機から書いている記事ですので、整合性は正直どうでも良いです。クリーンアーキテクチャについてはよくわかりませんでしたが、依存性の注入やインターフェースは便利だな〜、という感想です。
以上、おわり。
〈プリザンターを使った業務をすこし早くする方法〉をご紹介します

# はじめに

インプリム所属エンジニアのhmineです。
今日はプリザンターを利用する全ての方にお伝えしたい便利な機能をご紹介します。

# プリザンターのこんな業務をもっと早くできます！

- **業務1.　添付ファイルの内容を見たいとき。**
  - [ワンクリックで中身を確認できる機能](#1添付ファイルの内容をクリック1回で見る方法)をご紹介します！
- **業務2.　フィルターを設定したいとき。**
  - [必要なフィルターが設定された一覧画面を、ワンクリックで表示できる機能](#2必要なフィルターが設定された状態で一覧を表示する方法)をご紹介します！

ご紹介する機能はほんとうに便利なので、ぜひ使ってみてください。

---

# 【1】添付ファイルの内容をクリック1回で見る方法

## 「ダウンロード」フォルダを探さなくても、添付ファイルの中を見られるのはご存じでしたか？

普段、添付ファイルをどのように開いていますか？
図のように、添付ファイルのリンク文字をクリックする場合が多いのではないでしょうか。
そうした場合、添付ファイルはOSの「ダウンロード」フォルダに保存されます。この「ダウンロード」フォルダにはファイルがたまりがちで、「今すぐ中を見たいのに探すのが少し手間で・・・」となってしまいやすいと思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/0db88c4d-89ca-015b-3d6e-1025419d3a7f.png)

## 添付ファイル名の横の虫眼鏡アイコンをクリックすれば、ワンクリックで内容を見られます！

実は、リンクの左横についている虫眼鏡アイコンには、クリックするとファイルをそのままブラウザで開いて表示する機能があります。
このアイコンをワンクリックするだけで、すぐにファイルの内容を閲覧できるのです！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/157d3e69-4700-4efc-19d8-11715dbaf6c4.png)

プリザンターから添付ファイルを確認する機会が多いのであれば、これは覚えておいて損はない機能です。
この機能は、PDFを含む【ブラウザが閲覧をサポートしている形式】が対象となります。

- PDF
- TXT
- PNGやJPG等の画像

---

# 【2】必要なフィルターが設定された状態で一覧を表示する方法

## テーブルのフィルターの設定を変えた後は、毎回元に戻さないといけなくて・・・

一覧の中から必要な条件でレコードを絞り込むフィルターを活用すれば、目的のデータだけを表示できて便利ですが、いくつもフィルターを切り替えていると、だんだん手間になってきて、操作の間違いの元になってしまいます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/f026f89f-8f2e-0bb2-a44a-50237f954310.png)

## 今見ているフィルターの状態が保存されたURLを、ボタンひとつでコピーできます！

パンくずの一番左の「トップ」の横にある鎖の絵のアイコンをクリックしてください。
「?」の後にバイナリ文字が続く長いURLがコピーされます。
このバイナリ文字には、テーブルに対してフィルターの設定を指示する情報が含まれているので、コピーしたURLをブラウザに入力すれば、今表示されているフィルターの状態がそのまま設定されたテーブルを開くことができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3658415/a21aae62-5deb-c0d1-da53-a9fb1c9ef475.png)

このように、手作業でひとつずつフィルターを設定しなくても、鎖の絵のアイコンから取得したURLを手元に保存しておけば、そのURLを入力するだけで一覧にフィルターを設定でき、かなりの手間が短縮されます。

---

# おわりに

プリザンターの便利な機能の情報は、これからもQiitaで発信したいと思います。
ここまで読んでくださり、ありがとうございました！
【PostgreSQL】データベースチューニングについて

## 初めに
データベースのチューニングは、システムのパフォーマンスを向上させるために行われる重要な作業の一つです。しかし、データベースのチューニングは専門的な知識を必要とするため、まずは簡単にどんなことするのかを以下にまとめていきます。

### データベースチューニングとは
データベースチューニングとは、データベースのパフォーマンスを改善するための一連の手順やプロセスのことを指します。これには、データベースの設定の最適化、クエリの最適化、インデックスの設定や調整、ハードウェアの最適化などが含まれます。

### データベースの設定最適化
データベースの設定を最適化することで、パフォーマンスを向上させることができます。例えば、メモリの使用量、キャッシュサイズ、同時接続数、ログの詳細度など、データベースのパフォーマンスに影響を及ぼす設定は多数あります。

これらの設定は、データベースの種類やバージョン、使用しているハードウェア、アプリケーションの要件によって異なります。設定を変更する前に、その影響を理解し、必要ならば変更後のパフォーマンスをテストすることが重要です。

### クエリの最適化
クエリの最適化は、データベースチューニングの中でも特に重要な部分です。効率的なクエリは、データベースのパフォーマンスを大きく向上させます。

- 適切なインデックスの使用
- WHERE句でのデータの絞り込み
- JOINの最適化
- サブクエリとビューの使用

など、クエリの書き方によってデータベースのパフォーマンスは大きく変わります。

### インデックスの設定と調整
データベースにインデックスを適切に設定することで、データの検索速度を大幅に向上させることができます。しかし、インデックスはデータの更新時にもメンテナンスが必要なため、適切なバランスが求められます。

### ハードウェアの最適化
データベースのパフォーマンスは、使用しているハードウェアにも大きく依存します。ストレージ、メモリ、CPU、ネットワークなど、データベースのパフォーマンスに影響を及ぼすハードウェアは多数あります。

ハードウェアの最適化には、以下のような要素が考えられます。

- 高速なストレージ（SSDなど）の使用
- メモリの増設
- マルチコアCPUの利用
- 高速なネットワークインターフェースの使用

### まとめ
データベースのチューニングは、システム全体のパフォーマンスを向上させるための重要な作業です。しかし、パフォーマンス改善のための手法は多岐にわたり、それぞれのシステムやアプリケーションの要件によって適切な手法は異なります。ここで述べた基本的な手法を理解し、それを基にシステムの要件に合わせたチューニングを行うことが重要です。
Databricksアシスタントを用いた日本語によるLakeviewダッシュボードの作成

「未来は手のひらの上に」と思わざるを得ません。

<iframe width="560" height="315" src="https://www.youtube.com/embed/Ye-8tHVY92c?si=QV1prAd86rljDWE8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

こちらの機能です。

https://docs.databricks.com/ja/dashboards/lakeview-create-w-db-assistant.html

元々Lakeviewはノーコードでダッシュボードを作れる機能でしたが、[Databricksアシスタント](https://www.databricks.com/jp/blog/introducing-databricks-assistant)と組み合わされることで、自然言語でダッシュボードを作ることができます！

テーブルは指定します。日本のCOVID-19感染者数のデータです。(そのうち、このステップも不要になりそう)
![Screenshot 2023-12-21 at 16.02.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/7c962165-5a55-c43b-bde0-02c3900eca01.png)

Canvasに移動してビジュアライゼーションを追加するとプロンプトを入力できるようになっています。
![Screenshot 2023-12-21 at 16.03.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/95c25120-4a6b-f1ab-d94c-f2090dbe36af.png)

> 都道府県別比率

と入力します。

勝手に円グラフになりました！
![Screenshot 2023-12-21 at 16.03.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/6ee09e0e-39bc-31c4-ed77-217f539659a7.png)

次は、

> 月毎の感染者数の変化

![Screenshot 2023-12-21 at 16.03.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/75a79971-86c2-7cec-aaf9-f685b55debd4.png)
![Screenshot 2023-12-21 at 16.03.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/34836026-c26b-1c5d-1193-0f33b144bd32.png)

今度は折れ線グラフです！(興奮しすぎ)

ますます、自然言語が新たなインタフェースになってきてます。ぜひお試しください！

### Databricksクイックスタートガイド

[Databricksクイックスタートガイド](https://www.amazon.co.jp/dp/B09V1YXFVQ/)


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)