OmniAICreator/Qiita-1.07M huggingface dataset:
MIDIキーボードをゲームのコントローラーにしてみた話

## 音が出せるだけじゃないはず
MIDIキーボードは音楽活動に使われるイメージが大きいですが、仕組みを考えるともっと幅広い使い方ができるように思えます。一つ一つの鍵盤がスイッチだと考えれば、押したらオン、離せばオフのようなシンプルな仕組みと捉えられるはずです！
そこで今回は、実際にPythonを使ってMIDIキーボードの入力を取得して、いろいろと遊んでみました。


## MIDI入力を取得する
まずはとにかく入力を見てみたいですよね。どんな仕組みでキーボードが動いているのか確認してみます。

### pygame.midi
`pygame.midi`を使うと、PythonでMIDI入力を取得できるらしいです。
pygame自体はPythonではおなじみのゲーム制作ライブラリですが、その中にmidiを取得できる機能が付属していました。早速動作確認。
```python
import pygame.midi as m

### midiキーボードを初期化
m.init()
i = m.Input( m.get_default_input_id() )

while True:
    if i.poll(): # MIDIを受信するとTrue

        # MIDI入力を取得
        midi_events = i.read(4)
        print(f'events: {midi_events}')

```
こんな感じに書くと、midi_eventsの中に取得したMIDI入力が入るらしい。
```
events:[[[status, data1, data2, data3], timestamp]]

events: [[[144, 67, 45, 0], 10]]
events: [[[248, 0, 0, 0], 20]]
events: [[[248, 0, 0, 0], 40]]
events: [[[144, 67, 0, 0], 55]]
...
```

`status` : オン（144）かオフ（248）
`data1` : ノート番号（C:60 C♯:61 D:62 ...）
`data2` : 音量（0 ~ 127）
`data3` : チャンネル
`timestamp` : 経過時間

と意外にもいろんな情報が入ってました。それぞれ何か使えそうですね。


## 特定のキーをスイッチにしてみる
先ほど確認した入力をもとに、特定のキーをスイッチにしてprintさせてみます。
```python
note = midi_events[0][0][1] # ノート番号

if note == 60: # C3
    print('hello')
```
```
hello
hello
```
設定したノート番号60、C3を一回だけ押してみました。あれ？
押した時に１回、離した時にもう１回反応しました。出力を確認すると、
```
events:[[[status, data1, data2, data3], timestamp]]

events:[[[144, 60, 50, 0], 10]]
events:[[[144, 60, 0, 0], 40]]
```
キーを離した時、同じ音を音量0で入力した扱いになっていることが分かりました。また気になるのが、`status`は144でオン。ややこしい。
MIDIではキーを離した時も１つのイベントと捉えられるようです。はえー。
### コードを修正
```python
note, vol = midi_events[0][0][1:2] #　情報を取得

if vol != 0 and note == 60: # C3
    print('hello')
```
```
hello
```
キーを離した時音量は0になるので、音量が0でないことを確認するように修正したら、無事スイッチの形ができました。

## コントローラーを作れるのでは
PCゲームは、マウスでの視点移動が必要なゲームを除けば、操作の全てがキーボードで完結します。またキーボードの操作も、wキーを長押しして前に移動、spaceキーでジャンプ、xキーで何かを発動するなど、キーの押し離しのみで非常にシンプルです。
ということは、midiキーボードはコントローラーとして使うことができるのでは...？と思いました。
### 仕組みを考える
PyAutoGUIを使って、PCのキーボードを直接制御することができます。
例えば`pyautogui.press('x')`でxキーを押せたり。
MIDIキーボードのキー１つ１つを新しいキーとしてPCに認識させるのは難しいので、今回はこれを使うことにしました。
```python
# ド
if note == 60:
    key = 'x'

if note == 61:
...

# 長押し判定
try:
    if vol != 0:
        pyautogui.keyDown(key)
    else:
        pyautogui.keyUp(key)

except ValueError: # 何も押してない時
    pass
```

### 流石にコードを直す
１つ１つのキーで条件分岐していたらキリがないので、こんな感じのjsonで設定できるようにしました。
```json
[
    {
        "midi" : 60,
        "key" : "f"
    },
    {
        "midi" : 61,
        "key" : "r"
    }
]
```

## できた
完成した全コードはGitHubで配布してます。
使い方も記載したので、是非使ってみてください！

追記(2024/3/21): 全体的に動かなくなっていたので、仕様含め更新しました。

https://github.com/toripppppy/midify

実際に動かしてみる（ゲームはMuseDash）
![IMG_6598_AdobeExpress.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3073290/27907f03-5b3d-d8bb-f197-0f5454bff0b1.gif)
シンプルな操作の音ゲーなら簡単に対応できました。遅延も無く（ここすごい）長押しも問題なくゲームセンターの筐体のような感覚で遊べました！楽しい！
（マイクラにも挑戦中ですが、キー配置に苦戦中です...）

## おわりに
意外にも操作性はかなり高く、音楽関係を超えた場面でのMIDIの可能性を感じました。もっといろんな使い方が見つかりそうです。
今家にあるMIDIキーボードは音の強弱にも対応しているので、その機能と組み合わせたゲームを自作するのもまた面白そうですね。
以上、ロマンをお届けしました！
ROS2プログラミング基礎_4-1: ローンチファイル(launch file)の作成_1(最もシンプル)

## はじめに
こちらの書籍を参考書としてROS2プログラミングの勉強をしていきます．

https://www.kspub.co.jp/book/detail/5289563.html

このページではローンチファイルを作成します（参考書ではp.249）
ローンチファイルは一括して複数のノードを立ち上げたり，ノードのパラメータを設定したり，ノード名やトピック名を付け替えるリマップに関する情報を含むPythonスクリプトです．

#### まとめて立ち上げる自作のノード
今回練習として過去に作成した下記２つの自作ノード

「my_image_canny_node」(ROS2プログラミング基礎_3-2)
https://qiita.com/pez/items/99ed918900f7c8517c13
「my_gamepad_node」(ROS2プログラミング基礎_1-3)
https://qiita.com/pez/items/9d100183d8bac3b9e18f

を同時に立ち上げるだけの最もシンプルなローンチファイルを作成してみます．


## 環境
・PC: Panasonic Let's Note CF-FV
・OS: Windows11 Pro (64bit)
・VirtualBox: 6.1.38 (Ubuntu20.04.5, GUI環境)
・ROS: ROS2 Foxy

・ロボット：
　Turtlebot3 burger (Raspberry Pi 3B+)
　Turtlebot3 waffle pi (Raspberry Pi 3B+)
　Turtlebot3 waffle pi (Raspberry Pi 4B)
　※いずれも同様の操作でOK

・ゲームパッド：Logicool F710

## ローンチファイルの作成
今回名前は「mylaunch.launch.py」としておきます．
作成場所はホームフォルダ直下の launch ディレクトリとします．
```ruby:
$ cd
$ midir -p launch
$ cd launch
$ emacs mylaunch.launch.py
```
中身は下記のように記述し保存して下さい．
my_image_canny パッケージの my_image_canny_node と，
my_gamepad パッケージの my_gamepad_node を立ち上げる
という中身になっています．

```ruby:mylaunch.launch.py
from launch import LaunchDescription
from launch_ros.actions import Node

def generate_launch_description():
    return LaunchDescription([
        Node(
            package='my_image_canny',
            executable='my_image_canny_node',
            ),
        Node(
            package='my_gamepad',
            executable='my_gamepad_node',
            )
        ])

```


## 動作テスト(TurtleBot実機)
今回はロボットを動かすプログラムなのでロボットを起動します．
TurtleBot3の設定については別記事参照．
https://qiita.com/pez/items/1d3d15b3911d5dab1702

※下記２つはロボット側でコマンド入力
```ruby:TurtleBot3にて(SSH接続などで)
$ ros2 launch turtlebot3_bringup robot.launch.py
```

```ruby:TurtleBot3にて(さらに別のターミナルからSSH接続)
$ ros2 run usb_cam usb_cam_node_exe
```

#### 自作ローンチファイル実行
ファイルがある場所で単純に先ほど作成したpythonスクリプトを実行します（最も簡単な実行方法）
```ruby:自作の launch file を実行
$ cd ~/launch/
$ ros2 launch my_launch.my_launch.py
```

TurtleBot3に接続したUSBカメラの画像が２つ表示（１つは元画像，もう１つはエッジ検出結果）された上，gamepadによる操作が可能な状態になっていれば成功です．

## 補足
ローンチファイルの中身ですが，今回記述した「package」と「executable」は必ず記述が必要なものとなっています．その他にもパラメータを指定したりノード起動時に新しいターミナルを開くなどの色々な設定が可能ですがそれはまた別の記事にしたいと思います．
Nuxt3の初期設定 eslint+prettier+husky+lint-staged

# Nuxt3と基本的な設定

v3.0がリリースされ IntelliJ 系の対応もされてきたのでだいぶ快適に使えるようになってきました。
ここでは初期インストールと基本的な設定で開発のベースになる設定を記載していきます。

## 公式ドキュメント

https://nuxt.com/docs/getting-started/installation

これに従ってインストールしていくだけです。
（pnpmを使っていきます）

## さっそくインストール & テスト起動
```
pnpm dlx nuxi init <project-name>
cd <project-name>
pnpm install
pnpm run dev -o
```
これだけですね:expressionless:
※WARN  deprecated がでますが依存パッケージなのでどうにも:confused:

ブラウザが開いてNxutのロゴの起動中画面が暫く表示されたのち、↓の画面がでれば起動完了です。
![Welcome-to-Nuxt-.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3072031/8d6c3774-ad1b-8d8c-82c7-a773a59904fc.png)

## モジュールのインストール

```
pnpm install -D @nuxtjs/eslint-config-typescript eslint eslint-config-prettier husky lint-staged prettier typescript
```
`@nuxtjs/eslint-config-typescript`
でnuxt+typescriptで必要なもろもろのモジュールが付随しているので elist-config-oooo は prettier のみで済みます。

## .eslintrc

`@nuxtjs/eslint-config-typescript` と `prettier` の設定を追加します。
```
{
  "extends": [
    "eslint:recommended",
    "@nuxtjs/eslint-config-typescript",
    "prettier"
  ],
  "rules": {
    "no-console": "off"
  }
}
```

## .prettierrc

こちの中身はお好みで
```
{
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none"
}
```

## package.json

husky と lint-staged の設定を追記します。

```
{
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "*.{ts,vue}": [
      "prettier --write",
      "eslint --fix"
    ],
    "*.{md}": [
      "prettier --write"
    ],
    "*.{css,vue,sccs}": [
      "prettier --write"
    ]
  },
}
```
テーブルヘッダを結合させたいとき

# 背景
![スクリーンショット 2022-12-20 11.24.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/360072/10d848a1-7df6-2be7-15bf-186f13161577.png)

こんな感じの表をHTMLで実装したいとします。
ポイントは結合しているヘッダです。
果たしてどうやって実装するのでしょうか？

# 実装
```html
<table>
  <col>
  <colgroup span="2"></colgroup>
  <colgroup span="2"></colgroup>
  <thead>
    <tr>
      <td rowspan="2"></td>
      <th colspan="2" scope="colgroup">Mars</th>
      <th colspan="2" scope="colgroup">Venus</th>
    </tr>
    <tr>
      <th scope="col">Produced</th>
      <th scope="col">Sold</th>
      <th scope="col">Produced</th>
      <th scope="col">Sold</th>
    </tr>
  </thead>
  <tbody>
    ~~~
  </tbody>
</table>
```

こうなります。
`<colgroup>`とか`<th colspan>`とか、生でテーブル実装していない方だと
見慣れないものかもしれません。
実際私も見慣れないものでした。

# colgroup
`<colgroup>`とは、列のグループを定義するものです。

`<colgroup>`は`<table>`の子要素として配置され、
かつ`<thead>`の前に置かれます。

```html
<table>
    <colgroup span="2">
    <thead></thead>
    <tbody></tbody>
</table>
```

そして、`span`属性により`<colgroup>`要素がまたがる列の数を示します。
上記の例であれば、2列にまたがるグループを定義しているということです。

# th colspan
`<th>`は表の見出しセルを定義します。
そして、`<th>`に指定する`colspan`は**セルを幾つの列に広げるか**を示します。

```html
<table>
    <colgroup span="2">
    <colgroup span="2">
    <thead>
        <tr>
            <th colspan="2" scope="colgroup">hoge</th>
            <th colspan="2" scope="colgroup">fuga</th>
        </tr>
        <tr>
            <th scope="col">hoge 1</th>
            <th scope="col">hoge 2</th>
            <th scope="col">fuga 1</th>
            <th scope="col">fuga 2</th>
        </tr>
    </thead>
    <tbody></tbody>
</table>
```

そして`scope`属性によって見出し要素が関連するセルを定義しておきます。
この場合は先に定義した`colgroup`を指定することで、
この見出しが列グループに属し、その中の全てのセルに関連することを定義します。

グループ化したヘッダカラムの中に属する2段目ヘッダカラムには`scope="col"`を指定することで、
グループ化したヘッダカラムの列に属する全てのセルに関連することを定義しています。

# 参考
[Tables with Irregular Headers](https://www.w3.org/WAI/tutorials/tables/irregular/)
[colgroup: 表の列グループ要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/colgroup)
[th: 表見出し要素](https://developer.mozilla.org/ja/docs/Web/HTML/Element/th)
【雑談】エディタ戦争に付き合う方法

# はじめに
- [LIGTHzアドベントカレンダー 2022](https://qiita.com/advent-calendar/2022/lightz)の20日目の記事です。

- エディタに強烈な思い入れの無い人が、エディタに強烈な思い入れのある人に
相槌を打つ方法を書いています
- 独断と偏見に基づいています
- エディタへの思い入れは、エディタの使い方と深い関係があると思われます
- マニアックな使い方をしている人ほど、マニアックな思い入れがあります
- エディタ推しへの共感は、推してくる人の仕事へ共感を持つ事から始まります

# エディタ戦争に巻き込まれやすい時

- 普段は仕事上で深い付き合いのない部署が、共通のプロダクトなどを開発する事になった時
- 業種の異なる会社と協業を始めた時
- 異動、転職した時

# エディタ毎の推しポイントとユーザーのプロファイル
普及度の高いと思われる順に並べています。
### サクラエディタ・terapad・秀丸
　（推しポイント）　インストールが楽で設定変更もいらない。
　　　　　　　　　　コーディングも含めなんにでも使える。
　　　　　　　　　　使うための知識を身に着ける必要がない。
　（プロファイル）　普通の人が多い。ニュートラルに接すれば大丈夫。

### excel/パワポ
　（推しポイント）　図表の表現手段が豊富。インストールが楽で設定変更もいらない。
　　　　　　　　　　使えるユーザーが多い。
　　　　　　　　　　excelはcsv経由である程度Linux側と連携できる
　（プロファイル）　書式や配置に厳しい人が多いので、図表のシンメトリや体裁には注意する。
　　　　　　　　　　パワポでは文字数も極力すくなくする（ワンスライドワンメッセージ！）

### vscode
　（推しポイント）　図表の編集手段が豊富。ソフトウェア実装やデータ分析との親和性が高い！
　　　　　　　　　　python系環境構築の支援アプリが手厚い。
　（プロファイル）　トレンドに敏感な人が多い。
　　　　　　　　　　ユーザーによって使い方や推しポイントが幅広で一度に覚えようとすると
　　　　　　　　　　混乱するので、
　　　　　　　　　　利用目的を固定して一つ一つ操作方法を覚えるといい。

### emacs
　（推しポイント）　コーディングのコンパイラやlint checkerとの連携手段が豊富。
　　　　　　　　　　インストールが比較的楽でカスタマイズのバリエーションも豊富。
　　　　　　　　　　メーラー機能が軽く、
　　　　　　　　　　かつメールボックスの構造が単純でコマンドラインから整理しやすい。
　（プロファイル）　この辺からマウスを使って編集していると怒りだすユーザーが出てくるが、
　　　　　　　　　　Linuxの使い方を教えてくれるのでアドバイスは素直に聞く。
　　　　　　　　　　windowsのショートカットキーと癖が違うので、覚えるのに時間がかかる。

### vi/vim
　（推しポイント）　（主にLinuxや組み込み系）
　　　　　　　　　　操作方法やインストール可能な環境に対し、制限のある状況でも使える。
　　　　　　　　　　ユーザーも環境構築に強い手練れが多い。
　　　　　　　　　　慣れるとキーボード操作で何でもできる（らしい）。
　（プロファイル）　推してくる場合は自分の仕事を手伝わせようとしている場合が
　　　　　　　　　　ままあるので、巻き添えを食いたくない時は注意する。
　　　　　　　　　　取っつきは猛烈に悪いので、覚える場合、初期コストの負担を覚悟する。
　　　　　　　　　　動かなくなったり、キーボード操作通りに編集できない時は深呼吸して
　　　　　　　　　　escapeボタンか":q!"を押す。



# 付き合い方

- 推しポイントが、自分の好みとずれていても逆らってはいけません

- 推しポイントが、自分の業務に関係していなくても深追いしない方が良いです

- 推されたエディタを使う羽目になった場合は、エディタの使われ方から逆算して使い方を覚えると良いです
　例）『vscodeって見た目emacsぽかったり、コードの真ん中に図が埋まってたり何がしたいのかようわからんな』
　→ 　『みんなpython書くのに使ってるから図を見ながらコーディングしたいのかな？』
　→　 『あー、matlabとかと似た感じね』
　→　 『図もgnuplotみたいな感じで出してるのか』

# 参考資料
- テキストエディター戦争は「Vim」がまた一歩リードか、Webブラウザーで動作可能に
　https://forest.watch.impress.co.jp/docs/serial/yajiuma/1131850.html
- viコマンドについて詳しくまとめました 【Linuxコマンド集】
　https://eng-entrance.com/linux-command-vi
- 「Emacsのトラノマキ」連載第16回「元Vimmerが考えるEmacsの再設計」(深町英太郎)
http://dev.ariel-networks.com/wp/documents/aritcles/emacs/part16/
- 外資系コンサルのスライド作成術―図解表現23のテクニック
https://www.amazon.co.jp/%E5%A4%96%E8%B3%87%E7%B3%BB%E3%82%B3%E3%83%B3%E3%82%B5%E3%83%AB%E3%81%AE%E3%82%B9%E3%83%A9%E3%82%A4%E3%83%89%E4%BD%9C%E6%88%90%E8%A1%93%E2%80%95%E5%9B%B3%E8%A7%A3%E8%A1%A8%E7%8F%BE23%E3%81%AE%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-%E5%B1%B1%E5%8F%A3-%E5%91%A8/dp/4492557202
ddにfirst-childが効かない

# やりたいこと
dl(説明リストタグ)の一番上のddタグに上のボーダーつけたい。
```html
<div class="news">
<h2>News</h2>
<dl>
  <dt>2020.XX.XX</dt>
  <dd>デザイン雑誌「ＸＸＸＸＸＸ Vol.11』に掲載していただきました。</dd>　←このddに上のボーターをつけたい
    ~~　中略　〜〜
</dl>
</div>
```

![スクリーンショット 2022-12-20 10.55.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3014485/33b831b7-8975-74be-48c3-fa6b564c0d08.png)

## 失敗したコード
```css
dt:first-child,
dd:first-child {　← これが効いていない
  border-top: 1px solid #c8c8c8;
}
```

# 原因
`first-child`は全体のタグを含めた中の要素からfirst（1番目）という指定になるみたいです。
```html
<div class="news">
<h2>News</h2>
<dl>
  <dt>2020.XX.XX</dt>　← これが１番目！
  <dd>デザイン雑誌「ＸＸＸＸＸＸ Vol.11』に掲載していただきました。</dd>　←１番目じゃないのでfirst-childが適用されない
    ~~　中略　〜〜
</dl>
</div>
```


# 対処法

```css
dt:first-child,
dt:first-child + dd {
  border-top: 1px solid #c8c8c8;
}
```
「+」は、指定した要素に隣接する要素にスタイルを適用します。
これで`dt:first-child`から隣接するddにスタイルを適用できます。

![スクリーンショット 2022-12-20 10.53.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3014485/ce7bfba0-6e83-3bf2-55be-70ba7c2fc615.png)
DOMについての備忘録

今回は社内で勉強会を開催するにあたって
DOMについて勉強したので、備忘録として残します。

操作方法ではなく、DOMという概念をざっくり知りたい方はぜひ読んでみてください！

## DOMとは
DOM（Document Object Model）とはなんぞや？


>Document Object Model(DOM)は、HTMLまたはXML文書のためのプログラミングAPI
>ドキュメントの論理構造と、ドキュメントへのアクセスや操作の方法を定義している

📌[DOM - 公式ドキュメント](https://www.w3.org/TR/WD-DOM/introduction.html)より

簡単にいうと、
✅ 主に**JavaScript**からHTMLドキュメント（又はXMLドキュメント）を操作するためのAPI
✅ APIをどのように実装するかの定義

この2つを指します。
<br>

DOMについて調べていて分かりづらいなと感じたのがこの部分で
定義（概念）と実装のやり方を共に**DOM**と呼ぶそうです。

<br>


### 🗒JavaScriptによる操作

前提として、DOMはいろんな言語での操作が可能です◎
実際にPHPやRubyにもDOM操作を可能にするライブラリがあります。
例：📌[Simple HTML DOM（PHP）](https://simplehtmldom.sourceforge.io/docs/1.9/)


しかし、DOMを実装する場所は主にWebブラウザであるため
**JavaScript**での実装がDOM操作において重要度が高いことになります＾＾

<br>



## DOMツリー
以下のような表を構成するHTMLドキュメントがあったとします。
```
<TABLE>
  <ROWS> 
    <TR> 
      <TD>Shady Grove</TD>
      <TD>Aeolian</TD> 
    </TR> 
    <TR>
      <TD>Over the River, Charlie</TD>
      <TD>Dorian</TD> 
    </TR> 
  </ROWS>
</TABLE>
```
このHTMLドキュメントを図で表現したものが以下になります。
      
![スクリーンショット 2022-12-19 23.16.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1534321/9a2651af-533f-b019-80dd-3ec0ace7f1a6.png)
（画像、HTML共に📌[DOM - 公式ドキュメント](https://www.w3.org/TR/WD-DOM/introduction.html)より）

上記の構造（図）を**DOMツリー**と呼びます。
こう見るとHTMLドキュメントは木を逆さまにしたような構造をしていますね＾＾

このような構造をしているため、実際にDOM操作では子要素を辿ることができます。

<br>

## DOMを構成するもの
### 🗒Node（ノード）

>Node はいくつもの DOM API オブジェクトタイプが継承しているインターフェイスで、それらのさまざまなタイプを同じように扱える (同じメソッドのセットを継承する、または同じ方法でテストできる) ようにします。

📌[Node - MDN](https://developer.mozilla.org/ja/docs/Web/API/Node) より

上記のDOMツリーの画像でいう`<TABLE>`や`<ROWS>`といった
1つ1つのツリーの要素を**Node**と呼びます。


よく聞くもので言うと、`Document`や次に紹介する`Element`もNodeのうちの1つです。

<br>

### 🗒Element（エレメント）

>Element は Document の中にあるすべての要素が継承する、もっとも一般的な基底クラスです。
このインターフェイスは、すべての種類の要素に共通するメソッドとプロパティを記述するだけのものです。多くの具体的なクラスが Element を継承します。

📌[Element - MDN](https://developer.mozilla.org/ja/docs/Web/API/Element) より

上記のDOMツリーの画像でいう`<TD>Aeolian</TD>`のような
タグと中身の組み合わせを**Element**と呼びます。

よく耳にするものでいうと`HTMLElement`がありますが
これはHTMLの基本インターフェイスであり、親要素のNodeからプロパティを継承します。

<br>

## DOMの弱点

ユーザーに触れるHTMLドキュメントの裏側には
DOMが複雑な要素や属性を持っているため、
一見シンプルに見える画面の裏側で、DOMは多くの処理を強いられています。


また、子要素を複数持つ親要素が変更された場合、
親要素全体を再構築し、全てのコンテンツを再レンダリングする必要があります。。。

<br>

従って、ドキュメントの規模が大きくなればなるほど
DOMの仕事量は増大し、それに伴ってパフォーマンス低下の原因となるわけです。

<br>

### 🗒仮想DOMの登場

こうした懸念点を考慮した**仮想DOM**が誕生します！

>仮想 DOM (virtual DOM; VDOM) は、インメモリに保持された想像上のまたは「仮想の」UI 表現が、ReactDOM のようなライブラリによって「実際の」DOM と同期されるというプログラミング上の概念です。

📌[React - 公式ドキュメント](https://ja.reactjs.org/docs/faq-internals.html)より

仮想DOMとはVue.jsやReactといったJavaScriptライブラリによって
ブラウザ上に実装された概念を指します＾＾

仮想DOMの変更をリアルDOMと同期させ、その差分のみ反映させることができる
**差分検出処理**と呼ばれる特徴をもっています。

<br>


## 参考

何度かリンクを貼っていますが、DOMの公式ドキュメントです
📌[Document Object Model](https://www.w3.org/TR/WD-DOM/cover.html)

<br>

こちらの記事、大変わかりやすいうえに詳しすぎるところまで書いてあります！
神です、、、、
📌[業務ができる中級者になるためのJavaScript入門（DOM編）](https://zenn.dev/antez/books/6da596a697aa86)

<br>

## おわりに
今回はエンジニアとして知っておきたい
DOMに関する基礎知識を軽くまとめてみました！

自分のためにまとめたつもりですが、誰かの学習に少しでも役立てたら嬉しいです。
clusterでカメラ被写界深度を実装しよう!

この記事はクラスター[Advent Calender 2022](https://qiita.com/advent-calendar/2022/cluster) カレンダー2の20日目の記事です。
昨日は[@kaznishi](https://qiita.com/kaznishi)の[クラスター株式会社で半年過ごして思う、ココ好きポイント](https://blog.kaznishi.com/post/221219_cluster_advent_calendar/)でしたね。

## はじめに
こんにちは！8月からクラスター株式会社でSoftware Engineerをしている[@Sencha](https://twitter.com/konnich18757474)です。
自分が開発に携わり、10月のCluster Conference 2022 でも発表のあった「カメラ被写界深度」開発の様子を紹介していきたいと思います。

## カメラの被写界深度とは
そもそも被写界深度とはどういうものかというと、いわゆる「良い感じの写真」が撮れる機能のことです。
もう少し詳しく説明すると、被写体にピントを合わせてその前後をボケさせることができるものです。iPhoneにもポートレートという名称で存在しますよね。

![954bbf9b-fb90-43ee-9aee-1e4cf660daf7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315583/cb3dab7c-7c18-ddb9-a76e-0addfcafd4fe.png "clusterの被写界深度")

今回のカメラ被写界深度の機能では2つのモードを入れました。
画面の被写体にタッチすることでフォーカスすることができるオートフォーカスモード
画面上UIのスライダー、F値を調整することでフォーカスすることができるマニュアルフォーカスモード
オートフォーカスモードは簡単に被写界深度を使って撮影したい方、マニュアルフォーカスモードはよりボケ方や撮影距離を調整して写真を撮りたい方に向けたものになっています。

特にオートフォーカスモードでは、アバター・風景問わずどこにでもタッチしてフォーカスできるように作ることが必要でした。

## 被写界深度実装
それでは実際の実装方法についてです。仰々しい感じで説明しましたが、実は被写界深度のエフェクトを効かせること自体はそこまで複雑なことはしていません。今回はUnityのPostProcessing（以下: PPs）のDepth Of Field(以下: DoF)を使用していきます。

PPsのDoFには現実のカメラのようなパラメータが存在します。

- Focus Distance (撮影距離)
- Focal Length (焦点距離)
- Aperture (絞り, いわゆるF値)

撮影したい対象に合わせてパラメータを調整し、いい感じにボケた写真撮影を行えるようになります。
マニュアルフォーカスでは画像のようにUIでFocus DistanceとApertureの値を調整することができます。この際、Focal LengthはUnityのカメラコンポーネントの`FieldOfViewToFocalLength` という関数で計算しています。Unityのコンポーネントにはこういった便利な関数があってありがたいですね。

![IMG_0534.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315583/e6c6780f-319b-e449-ecb3-d4cf1b2f9310.png "マニュアルフォーカス")

さて、問題はオートフォーカス時のFocus Distanceです。値を取得する方法はいくつか考えられますが、前述した「アバター・風景問わずどこへでもフォーカスできる」といったことを考慮するとやり方は限られてきます。
そこで今回選択したのは深度から取得するといった方法です。
オートフォーカスの流れは以下のようになります。

1. カメラから得られた深度情報をshaderを介しグレースケール画像に変換（正規化する）
1. 変換したものをカメラのRenderTextureに反映
1. RenderTextureをTexture2Dに変換し、タッチした位置のカラー情報を取得
1. カラー情報（RGBどの値も0 ~ 1となっている）からDoFのFocus Distanceに反映

これでカメラに写っているものであればタッチしてFocus Distanceを取得することができるようになりました！無事実装完了です。

## おわりに
今回はカメラの新機能である被写界深度の開発事例について紹介しました。
個人的な感想ですが、リリース以降好意的なフィードバックが多く、SNSなどでも素敵な写真が共有されているのを見ると非常に嬉しく、達成感を感じることができました。
どんどん撮影して盛り上げていっていただければ嬉しいです！

明日は[@fatdesign](https://qiita.com/fatdesign)の「[伝わるビジュアルに落とし込むことの重要性](https://note.com/fatdesign/n/nd2afb65715e4)」ですね！お楽しみに！
GraphQLとは

入った案件でGraphQLを初めて扱うことになったので、それについて記事を書きました。

# GraphQLとは
2015年にfacebookが開発したクエリ言語です。
REST APIとやっていることはほぼ同じですが、データ通信量の面でGraphQLの方が負担が少ないという利点があります。
1回の実行で不要な値を取ることがないようにできたり、2度通信するということを防ぐことができます。
ソースコードで定義したコードを元にクライアントとサーバ側でデータの受け渡しができるため柔軟に作ることができます。

同じHTTPエンドポイントにクエリをPOSTするのが特徴。
GraphQLは、WEB/モバイルアプリ（HTTPクライアント）の開発者が、APIを呼び出すことで、バックエンドAPIから必要なデータを正確に取得できるように設計されています。

# クライアントサーバーにおけるGraphQLの処理フロー

・GraphQLクエリは、望んでいるJSONと似たフォーマットをしていますが、JSONではないです。そのため、「POST」リクエストを作成してGraphQLクエリをサーバーへ送信されますが、クライアントからは「文字列」になって送信されます。
・サーバーはJSONオブジェクトを取得して、クエリの文字列を抽出します。GraphQLの構文とグラフのデータモデル（GraphQLスキーマ）に従って、サーバーはGraphQLクエリの処理と検証を実施します。
・一般的なAPIサーバーと同様に、GraphQL APIサーバーはデータベースや他のサービスを呼び出して、クライアントがリクエストしたデータを取得します。
・サーバーはデータを取得し、JSONオブジェクトにしてからクライアントに返します。

# コード記述例

```graphql
type Root {
    person(id: ID): Person
}

type Person {
    id: ID
    name: String
    birthYear: String
    gender: String
    friendConnection: PersonfriendsConnection
}

type PersonfriendsConnection {
    friends: [Friend]
}

type Friend {
    name: String
    place: String
    relationship: String
}
```

### 解説
・Rootはルートとなる型で、サーバーへの問い合わせはここから始まります
・Rootはperson関数を持ち、関数は指定したidのPersonを返します
・Personはid、name、birthYearなどのフィールドを持ちます
・PersonのfriendConnectionフィールドは、PersonfriendsConnection型で、Personの友達（Friends）の配列です
・Friendはname、placeなどのフィールドを持ちます

# 所感
これまでREST APIしか使ったことがなかったです。
GraphQLを導入することによってコード転送量が減るので、ユーザーレスポンスは少し早くなりそうですね。
ただ実装がやや面倒になるので必要に迫られば導入を検討ですが、表示スピードをそこまで気にしないサービスであれば一般的なREST APIでいいのかなと思われます。

コードでクエリを管理して段々と拡張していけるので大きめのサービスでは効果的そうですね。
キャッシュ設計(4) - 部分

# 部分キャッシュ

この記事では部分キャッシュを扱います。

!<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940/ac9272ea-b34e-abe9-513b-6e64a445f865.png" width=200>

> 部分キャッシュは、よく“ドーナツキャッシュ(donut caching)”と“ドーナツの穴キャッシュ(donut hole caching)”の2つのカテゴリに分けられる
>
> -- [部分キャッシュとASP.NET](https://www.infoq.com/jp/news/2011/12/MvcDonutCaching/)

BEAR.Sundayは **ドーナツキャッシュ**、**ドーナツの穴キャッシュ**、どちらにも対応しています。部分キャッシュはページをキャッシュできる部分とそうでない部分に分けて管理しようという技術です。ちなみにドーナッツの語源はdo-nut cache(音がdo not cache)から来ています。

ドーナッツキャッシュ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940/be69059d-f283-be19-49ea-19f15f75455c.png)

## ESI

この部分キャッシュをCDNレベルで行うのがEdge Side Includes (ESI)です。

https://www.fastly.com/jp/blog/esi-and-the-story-of-libraries-built-for-the-edge

BEAR.Sundayではこれをサーバーサイドで実現することで、より効率的に部分キャッシュを実現しています。

## 設計と実装

以下のようなページの設計と実装を考えてみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3940/e72480af-b362-87b2-cda9-3a148da39fc2.png)


青のlayoutの部分はヘッダー、フッター、Navバーなどページのレイアウトなどで静的ですす。そのlayoutの中に、キャッシュできないコンテンツ(donut)があるとします。

```php
#[DonutCache]
class BlogPosting extends ResourceObject
{
    #[Embed(rel: "donut", src: "app://self/live-content")]
    public function onGet(int $id = 0): static
    {
        $this->body['article'] = 'hello world';

        return $this;
    }
}
```

`live-content`はリクエストの度に値が代わり、キャッシュすることができません。なのでページ全体はキャッシュすることも出来ません。生存期間０のETagは無意味なのでETagも付きません。

**しかし`article`をbodyにアサインして計算したLayoutはキャッシュされ、再利用されます**。

これは内部で小さなテンプレートエンジンを生成してレンダリングしているようなものです。以下のようなテンプレートを作っています

```html
<html> ...
...<p>hello world</p>
...
[le:app://self/live-content]
...
..
</html>
```

このテンプレートから埋め込みリンクの`app://self/live-content`を取得して、レンダリングしてプレースフォルダの`[le:app://self/live-content]`と入れ替えています。

コンテンツ全体のキャッシュは出来ないため、ネットワーク資源の節約は出来ません。しかし計算資源を最小化しています。二度目のリクエストで`onGet`メソッドの実行や、layoutテンプレートレンダリングが行われることはなく再利用されます。

## REST制約

これはBEAR.Sundayの、**URI**と**ステートレス**と**リソースはその表現を持つ**という３つのRESTの特性で可能になっています。

この問題を既存のMVCフレームワークがAOPなしでどう解決するかを考えてみてください。良い設計エクセサイズになるのではないでしょうか？

優れた制約は**考えてもいなかった問題を既に解決している**ことがあります。
BEAR.Sundayの実装を進めていく過程は、まさにこの認識の繰り返しでした。
CS合同勉強会開催中！

## はじめに
はじめまして！皆さまお疲れさまです。
CS（カスタマーサポート）歴10年超、アドベントカレンダー2年目のRyusei55と申します。本記事へのご訪問ありがとうございます！
本記事では、他社とのCS合同勉強会について、これまでの開催の経緯や今後目指していることについて、紹介させていただきます。
CSにご興味のある方、他社との合同の取り組みを検討されている方など、ぜひ最後までご覧ください。


## CS合同勉強会とは
ゲーム業界3社のCS担当者にて、以下大きく2つのテーマについての合同勉強会（意見交換会）を3か月に一度程度、オンラインで開催しています。
**①CS KPIの設定および活用**
**②CSスタンダードの検討**
<br> 

<INS>**①CS KPIについて**<INS>

CSの品質や状態を把握するためにはどのようなKPIを設定すればよいのか、またそのKPIをどのように活用すればよいのか、「応対品質」「安心安全」「付加価値向上」という3つの観点において、各社の状況や実際のデータも踏まえながら事例を共有し合い、ベストなKPIを策定を目指しています。

<INS>**②CS対応のスタンダードについて**<INS>

上記KPIが定量的な指標とすると、それ以外の定性的なテーマについて議論するのがこちらとなります。各社がCS業務の中で感じている課題や、昨今のお客さま層を踏まえて検討すべきことなど、それぞれの議題にそったCSとしてのあるべき姿＝CSスタンダードを策定することを目指しています。


## 合同勉強会で具体的に取り組んでいること
### ①CS KPIの設定および活用
これまでCS対応における品質や状態を定量的に表すというのが各社共通の課題でした。その課題に対してCS独自のKPIを設定し、それらを活用してCSの状態把握や、品質向上に繋げようというのが本取り組みの目的です。
具体的には「応対品質」「安心安全」「付加価値向上」という3つの観点において計39項目のKPIを洗い出し、そこから重要度を話し合い"必須/推奨/任意"の3段階の優先度を設定しました。そして各社で必須項目を中心にそれぞれのKPI定量データを取得し、実際にCS業務に取り入れ、その結果を3社間で共有することで、より有効活用できる方法を模索しています。
＜例＞※こちらは応対品質という観点で取得すべきKPIと優先度と活用手段をまとめたものです
![スクリーンショット 2022-12-20 200319.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348480/bc6321fa-6856-0878-686a-af00a0ba4605.png)





### ②CSスタンダードの検討
こちらのテーマでは通常のCS業務での課題や、昨今のトレンドを踏まえたホットな話題など定性的な議題について話し合っています。
具体的には、毎回各社持ちよりで興味のある議題を出し、その議題にそって現状/課題/対策などを話し合い、最終的には対応基準＝CSスタンダードとして何がベストかの結論をまとめるようにしています。
過去に議論したテーマの一例をご紹介します。
<br> 
<INS>**不正返金におけるBAN基準について**<INS>

不正返金を検知した際にどのような基準でBANをしているか、またどのようなことに気をつけなければならないかについて話し合いました。事前警告の要否や不正の見極めなどといった論点を踏まえ、最終的には「利用者保護」「環境保持」の2つの観点からCSスタンダード案を定めました。

<INS>**カスタマーハラスメントについて**<INS>

自社でカスハラをどう定義しているか、またカスハラに対しての対策や今後の課題などを話し合いました。カスハラとしての明確な基準の策定が難しいといった悩みや、今後お客さまに対してどう警告（啓発）していくかなど未来のCSのあるべき姿についても話し合うことができました。
※こちらについては議論が白熱したものあり、今後も議論を続けていくテーマとなっています！
<br> 
## 合同勉強会をしてよかったこと
今回定量面、定性面に分けて取り組みを行ったことにより以下の効果があったと思います。

<INS>★　KPIの設定とともに、算出手順や活用手段を定めることで、品質改善が必要となった際や、新規でCS運営を構築する際にも参考になる基準を作ることができた<INS>

⇒活用事例として「ストアレビュースコア」をKPIの1つとして設定した事例を紹介します。
Dailyでスコア推移を確認しレビュー返信を行い、且つ、レビュー内容を元にしたプロダクトへの改善提案を行った結果、レビュースコアが平均0.4pt向上しました。
またスコアの取得方法や活用方法の実績ができたことで、新規タイトルリリースの際にも同じフローを導入することができました。
![スクリーンショット 2022-12-20 102842.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2348480/0f9fe153-32fb-389f-f4fe-f8ebcaa995fd.png)
※リリース後、1週間と翌週での比較
<br> 

<INS>★　CSとしてのより良い対応基準や対応方法の知見を取り入れ自社の業務に生かすことができた<INS>

⇒事例として不正返金におけるBAN基準を各社で情報共有しあい、改めてあるべき基準について検討しました。結果として、事前警告の要否や不正の見極め基準を定めるとともに、ストア側での返金基準を確認したほうがよいのではないかという見解となり、基準を確認すべく社内法務とも連携しプラットフォーム側との協議に入ることができました。
<br> 
などなど、他社の状況や考え方を共有しあうことで、自分たちのCS対応が他社と比較するとどうなのかが見えてきたり、CSとしてのあるべき姿を定めることができたりと
井の中の蛙にならない！ということが意識できるようになったと思います。
　
## 本取り組みの今後の課題
大きく2つの課題があると考えています。
**・CS KPIやCSスタンダードをより実業務に活用していくこと**
**・合同勉強会の取り組みをもっと広く多くのCS組織に広め発信していくこと**

上記の課題に取り組んでいくことで、CS業界全体を盛り上げていきたい（付加価値を高めていきたい）と思うとともに、グリーCSとしても業界№1と言われるようなCSを目指していきたいと思います。

最後までご覧いただきありがとうございました！！
YAML unsafe_load + freeze で FrozenError が出た

## おおむね……

https://secret-garden.hatenablog.com/entry/2021/05/23/200803

この記事の追試みたいなものです．

## Psych 3.x

再帰な定義をしてみた．

```ruby
> require 'yaml'
=> true

" YAML.load(<<~EOL)
" a: &a
"   b:
"     <<: *a
> EOL
=> {"a"=>{"b"=>{}}}

" YAML.load(<<~EOL， freeze: true)
" a: &a
"   b:
"     <<: *a
> EOL
FrozenError: can't modify frozen Hash: {}
from psych-3.3.2/lib/psych/visitors/to_ruby.rb:375:in `block in revive_hash'
```
PythonでLocalStorageを操作する

# LocalStorageについて
LocalStorageは、Webブラウザーに保存されるデータを扱うためのAPIです。このAPIを使用することで、Webアプリケーションはブラウザー内に永続的にデータを保存できます。

LocalStorageは、JavaScriptを使用してアクセスできます。保存されたデータは、同じオリジン (プロトコル、ドメイン、ポート番号) を持つWebアプリケーションからのみアクセスできます。

Pythonでは、JavaScriptのLocalStorageを直接操作することはできませんが、PythonからSeleniumを使用することで、JavaScriptを実行することができます。

# コード
PythonでSeleniumを使用してLocalStorageにデータを保存してみます
```python
from selenium import webdriver

# Chromeを起動
driver = webdriver.Chrome()

# LocalStorageにデータを保存するJavaScriptを実行
driver.execute_script("window.localStorage.setItem('key', 'value')")

# LocalStorageからデータを取得するJavaScriptを実行
value = driver.execute_script("return window.localStorage.getItem('key')")
print(value)  # "value"が表示される

# Chromeを終了
driver.quit()
```
上記の処理の流れは、
Chromeを起動し、execute_scriptメソッドを使用してJavaScriptを実行しています。execute_scriptメソッドは、JavaScriptを実行して、結果をPython型で返すことができます。

# 補足
JavaScriptでLocalStorageを操作する方法

1.localStorageオブジェクトを取得します。
```JavaScript
const localStorage = window.localStorage;
```

2.データを保存するには、setItemメソッドを使用します。このメソッドには、保存するデータのキーと値を渡します。
```JavaScript
localStorage.setItem('key', 'value');
```

3.保存されたデータを取得するには、getItemメソッドを使用します。このメソッドには、取得するデータのキーを渡します。
```JavaScript
const value = localStorage.getItem('key');
```

4.保存されたデータを削除するには、removeItemメソッドを使用します。このメソッドには、削除するデータのキーを渡します。
```JavaScript
localStorage.removeItem('key');
```

5.LocalStorage内のすべてのデータを削除するには、 clear メソッドを使用します。
```JavaScript
localStorage.clear();
```

# 補足
LocalStorageには、データのサイズの制限があります。各ブラウザーで異なるため、保存できるデータのサイズには注意が必要です。また、LocalStorageはセキュリティ上の問題を引き起こす可能性があるため、センシティブなデータを保存するには適していません。
【Vue/I18n】言語切り替えにレスポンスする

Vue・I18nで多言語対応開発しているとき、言語切り替えに反応して処理を呼びたい場合にはどうすればいいでしょうか。

# 答え
```vuejs
watch: {
  '$i18n.locale': function(newLang) {
    //変更時の処理
    //切り替え後の言語はnewLangに
  }
}
```

なんとwatchの監視対象に文字列を用いると他インスタンスの変数も監視できるんですね。

# 参考
https://stackoverflow.com/questions/67141277/is-there-a-way-to-watch-a-change-of-the-i18ns-current-locale
[Delphi] Windows / macOS / iOS / Android でアプリのバージョン情報を取得する

# バージョン番号の指定

Delphi はプロジェクトオプションでバージョン番号を指定できます。

:::note info
Android は VersionCode / VersionName を指定できます。
VersionCode は連番で増えていくもので、VersionName は人間が読めるバージョン情報です。
今回は、VersionName を取得します。
:::

画像は各プラットフォーム毎のバージョン番号指定部分を赤枠で示したものです。

左上：Windows
右上：Android
左下：macOS
右下：iOS
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/12977/a8ace051-95b2-bcfc-704d-4ab1868479f1.png)

# バージョン番号を取得する

バージョン情報ダイアログにバージョンを表示するときやサポートにログを送って貰うときにログにバージョンを仕込んでおくとか、そういう時にバージョン情報が必要になります。

ということでプログラムからバージョン番号を取得する部分を関数にしました。
ソースは以下の通りです。

```delphi
(*
 * Application Version
 *
 * PLATFORMS
 *   Windows / macOS / iOS / Android
 *
 * LICENSE
 *   Copyright (c) 2022 HOSOKAWA Jun
 *   Released under the MIT license
 *   http://opensource.org/licenses/mit-license.php
 *
 * HISTROY
 *   2022/12/19 Version 1.0.0  First Release
 *
 * Programmed by HOSOKAWA Jun (twitter: @pik)
 *)

unit PK.Utils.Version;

interface

function GetVersion: String;

implementation

uses
  System.SysUtils
  {$IFDEF OSX}
  , Macapi.CoreFoundation
  {$ENDIF}
  {$IFDEF ANDROID}
  , Androidapi.Helpers
  , Androidapi.JNI.GraphicsContentViewText
  , Androidapi.JNI.JavaTypes
  , Androidapi.JNI.App
  , Androidapi.NativeActivity
  {$ENDIF}
  {$IFDEF IOS}
  , Macapi.Helpers
  , iOSapi.Foundation
  {$ENDIF}
  ;

function GetVersion: String;
begin
  Result := 'unknown';

  {$IFDEF MSWINDOWS}
  var Major, Minor, Build: Cardinal;

  if GetProductVersion(ParamStr(0), Major, Minor, Build) then
    Result := Format('%d.%d.%d', [Major, Minor, Build]);
  {$ENDIF}

  {$IFDEF OSX}
  var CFStr: CFStringRef :=
    CFBundleGetValueForInfoDictionaryKey(
      CFBundleGetMainBundle,
      kCFBundleVersionKey
    );

  var Range: CFRange;
  Range.location := 0;
  Range.length := CFStringGetLength(CFStr);
  SetLength(Result, Range.length);

  CFStringGetCharacters(CFStr, Range, PChar(Result));

  Result := Result.Trim;
  {$ENDIF}

  {$IFDEF IOS}
  var Ver :=
    TNSBundle
    .Wrap(TNSBundle.OCClass.mainBundle)
    .infoDictionary
    .objectForKey(StringToID('CFBundleVersion'));

  if Ver <> nil then
    Result := NSStrToStr(TNSString.Wrap(Ver));
  {$ENDIF}

  {$IFDEF ANDROID}
  var Activity :=
    TJNativeActivity.Wrap(PANativeActivity(System.DelphiActivity)^.clazz);
  var Info :=
    Activity.getPackageManager.getPackageInfo(Activity.getPackageName, 0);

  Result := JStringToString(Info.versionName);
  {$ENDIF}
end;

end.
```

# さいごに
[GetProductVersion](https://docwiki.embarcadero.com/Libraries/ja/System.SysUtils.GetProductVersion) で全部のプラットフォームサポートしてくれたら良くない！？
Laravelで絞り込み検索に役立つ構文

# この記事について

キーワード検索＋日付絞り込み＋ソートなど複雑な絞り込みを行う際に条件を保持したり、eroquentの条件分岐をどう実装するかの備忘録

## 絞り込みSQL

### 「●●の時にwhere句をくっつける」

$keywordが存在している時、where句による絞り込みを行う。

```PHP
when(isset($keyword),function($query) use($keyword){
    return $query->where("name","LIKE","%" . $keyword . "%")
});
```

### 「( A or B ) or ( C and D )などの括弧付き条件を実装するには？」

```PHP
$users->where(function($query){
    return $query->where("条件A")->orWhere("条件B");
})->orWhere(function($query){
    return $query->where("条件C")->where("条件D");
});
```

### 「実例」

例）日報一覧のうち、「日付」が指定されていた場合、日付で絞り込み、さらに、キーワードが入力されていた場合、「案件ID,案件名,顧客名」のいずれかで絞り込みを行いたい。

```PHP
$assign["reports"] = ViewReport::when(isset($req->date), function($query) use ($date){
    return $query->where(function($query) use ($date){
        return $query->where("date",$date);
    });
})
->when(isset($req->key), function($query) use ($key){
    return $query->where(function($query) use ($key){
        return $query->where("project_id",$key)->orWhere("project_name","LIKE","%".$key."%")->orWhere("clients_name","LIKE","%".$key."%");
    });
})
->paginate(10);
```

## ページングした際に検索条件を保持

通常のページング

```PHP
{{ $projects->links('pagination::bootstrap-4') }}
```

条件を保持する書き方

```PHP
{{ $projects->appends(request()->query())->links('pagination::bootstrap-4') }}
```
【Z】zから始まる日本語入力ショートカット

意外と知られてないけど有用なので。

|入力|出力|
|:---:|:---:|
|z/|・|
|z.|…|
|z,|‥|
|zh|←|
|zj|↓|
|zk|↑|
|zl|→|
|z-|〜|
|z[|『|
|z]|』|

少なくともGoogle IMEだとこれが使えます。
【Y】Youtube埋め込みをレスポンシブなサイトに埋め込む

Youtubeからコピーしたものをそのまま書いたらwidth属性のせいではみだしたりするんですよね

## 結論

周りをdivで囲んでaspect-ratio使うとなんとかなります

```html:example.html
<div style="width:100%;aspect-ratio:16/9">
    <iframe style="width:100%;height:100%;" width="1920" height="1080" src="https://www.youtube.com/embed/XXXXXXXXXXX" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
</div>
```

Youtubeに限らず、iframeに汎用的に使えるはず。
enebularでnode-red その2

# 概要
enebularでnode-redやってみる。
練習問題やってみた。

# 練習問題
九九を実行せよ。

# フローと実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7567cf30-54eb-33a3-58a9-93f1aafc9a4b.png)


# 各functionのコード

- init

```
msg.i = 1;
return msg;

```

- print

```
msg.payload = "";
for (var j = 1; j < 10; j++)
{
    msg.payload += msg.i * j + " ";
}
```

- inc

```
msg.i++;
return msg;
```

# 成果物

```
[{"id":"e22cd57c76adb3db","type":"inject","z":"4ff0fa05.a3df64","name":"start","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":90,"y":940,"wires":[["7294fae05382330d"]]},{"id":"f80c1750c1fd93ae","type":"debug","z":"4ff0fa05.a3df64","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":710,"y":940,"wires":[]},{"id":"308a5caf24b34cf0","type":"function","z":"4ff0fa05.a3df64","name":"print","func":"msg.payload = \"\";\nfor (var j = 1; j < 10; j++)\n{\n    msg.payload += msg.i * j + \" \";\n}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":450,"y":940,"wires":[["f80c1750c1fd93ae","63542b303e87d1c4"]]},{"id":"d40992afea22d909","type":"switch","z":"4ff0fa05.a3df64","name":"owari","property":"i","propertyType":"msg","rules":[{"t":"lt","v":"10","vt":"str"},{"t":"gte","v":"10","vt":"str"}],"checkall":"true","repair":false,"outputs":2,"x":450,"y":1020,"wires":[["b7c88add91c6cb1d"],[]]},{"id":"7294fae05382330d","type":"function","z":"4ff0fa05.a3df64","name":"init","func":"msg.i = 1;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":250,"y":940,"wires":[["308a5caf24b34cf0"]]},{"id":"63542b303e87d1c4","type":"function","z":"4ff0fa05.a3df64","name":"inc","func":"msg.i ++;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":290,"y":1020,"wires":[["d40992afea22d909"]]},{"id":"b7c88add91c6cb1d","type":"delay","z":"4ff0fa05.a3df64","name":"","pauseType":"delay","timeout":"100","timeoutUnits":"milliseconds","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"allowrate":false,"outputs":1,"x":610,"y":1020,"wires":[["308a5caf24b34cf0"]]}]
```

以上。
【X】XMLHttpRequestを何も考えずに使いたい

外部ファイルを持ってきたいとき〜！！

https://developer.mozilla.org/ja/docs/Web/API/XMLHttpRequest

## 結論

これをベースにすればだいたいなんとかなる

```js
let url = "https://example.com/"
let xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.responseType = "document"; // text, arraybuffer, blob, document, jsonが使用可能。jsonのresponseは自動パースされる
xhr.send();

xhr.onload = () => {
    if (xhr.status != 200) {
        console.log("取得に失敗");
    } else {
        /* やるべき処理 */
        /* xhr.responseにレスポンス文が入ってます */
    }
};
```

## better

Fetchがあるぞ

https://developer.mozilla.org/ja/docs/Web/API/fetch

```js
let url = "https://example.com/"
let response = await fetch(url);

if (response.ok) {
    /* やるべき処理 */
    /* 例えばjsonとしてとりたいなら"responce.json()"を変数にぶち込みます */
} else {
    console.log("取得に失敗");
}
```

responseに何が入っているかはここらへんを見るといいと思います

https://developer.mozilla.org/ja/docs/Web/API/Response

blobを取りたいなら`Response.blob()`、テキストを取りたいなら`Response.text()`みたいな感じ。
一度`Response.blob()`などをするともう一度書き出したりはできないらしいです。
プログラミング初心者だけど技術記事書いてよかった

# はじめに

Advent Calendar2022 に初参加してみました！


私は今年(2022年)の4月に初めてプログラミングに触れ、記事を書いている現在(2022/12/16)まで8か月ほどプログラミングを勉強してきました。

その勉強の一環としてQiitaに記事を投稿しております。

https://qiita.com/scythercas/items/4fdb672f6e4ebb13da1a

私がこんな記事書かなくても、既にある記事で事足りているものです。
敢えて初心者が書く必要ある？と思うこともあります。

しかし、こういう記事を含み20個ほど記事を書いてきて振り返ってみると、大いに自分のためになったと実感しています。

# 初心者が技術記事を書くメリット

大きく分けて2つあると思います。

## 記事を探している初心者にとって、気軽に開ける記事となる

私が初心者用の記事を開くとき、
> 「記事を書いている人が初心者だと分かれば、まず難しい単語はそれほど出てこないだろう。」

>「もし難しい言葉を使っていたとしてもその人が勉強する過程でその言葉が分からないときに調べるだろうから補足が入っているだろう。」

なんて無意識に推測しておりますが、実際初心者の方がその単語を調べた経験が新しいですから、説明が入っていることが体感多いです。

また、初心者の方が書いた記事だと必要以上の情報が少ない、ノイズが少ない場合が多いと思います。

記事を探す視点で初心者が書いた記事を開くメリットを書きましたが、逆を返すとその記事は初心者にしか書けないわけですから、これは初心者が技術記事を書くメリットになると思います。


## 技術に精通している人からコメントを頂ける

これが本当に大きなメリットです。

私の記事では、

https://qiita.com/scythercas/items/4fdb672f6e4ebb13da1a

https://qiita.com/scythercas/items/ef132e105da1fd0db4e8

https://qiita.com/scythercas/items/033689ff77f0a678f6b6

他にもありますが、これらの記事でコメントを頂いております。

詳しい方から、**「こんな方法もあります。」** **「この書き方もあります。」** などのアドバイスや、コードの指摘等を頂けることがあります。
特に独学で勉強している方はこういったアドバイスは凄く助けになると思います。

また、**Qiitaで記事を挙げてきた中で最も挙げてよかった**と思った記事があります。
それがこちらです。

https://qiita.com/scythercas/items/c476bcf92d83f534c522

技術記事ではないですが、本文よりコメント欄がメインとなってしまうくらいに様々なご意見を頂けました。

## 他にも良いことたくさん

+ モチベに繋がる
+ やる気が起きないときは何かアウトプットしようから勉強が始められる
+ 反応がもらえてきもちいい
などなど



# 最後に

僕なんかが、私なんかが挙げたところで意味ないよなんて思ってる方がいたら、だまされたと思って何か投稿してみてほしい。
組込ソフトウエア開発概説：イントロダクション

<h1>はじめに</h1>
ソフトウエア開発の経験が長くても、いきなり「組込ソフトウエアを開発しろ」と言われると面食らう方が多いのではないでしょうか。
インターネットで情報が取り放題の現在、がんばって検索するといつかは欲しい情報が揃うと思いますが、組込ソフトウエア開発の全体像を解説するまとめサイトがあったら役に立つだろうな、と考えました。
そんな思いから、ここでは初めて組込ソフトウエア開発がミッションとなったエンジニアの皆さんをターゲットに、組込ソフトウエア開発において何を考えて何を選択してどう組み上げていく必要があるのかを少しづつ解説していきます。


<h3>■組込機器とソフトウエア</h3>
「IoT：Internet of Things」という言葉がよく聞かれるようになったのは2014年ころだったでしょうか。それまでインターネットと言えば人間がパソコンでWWWなどを利用するものでしたが、今ではコンピュータ（マイコン）が内蔵されている電子機器＝組込機器が社内LANやインターネットを介して他の機器と通信を行う、まさにモノのためのネットワークの時代となりました。マイコンには当然ソフトウエアが必要で、今後ますます組込機器向けソフトウエア＝組込ソフトウエアを開発する機会が増えて行くでしょう。
しかし、組込ソフトウエアの開発は、パソコン向けソフトウエア開発と大きく異なり、いろいろな事情や制約があります。そもそも、CPUやメモリ、各種デバイスが搭載されたハードウエアがあっても、それは「ベアメタル」と呼ばれる状態で、ソフトウエア的には空っぽです。全部自分で書くか、どこかからソフトウエア部品を入手して、組み合わせて使う必要があります。
これが、組込ソフトウエアの面倒なところだと思います。

<h3>■予定内容</h3>
大きくはこんな順番で書いていきます。

<b>第1シーズン 組込ソフトウエア開発概説
第2シーズン TCP/IPネットワーク
第3シーズン ネットワークセキュリティ
第4シーズン USBドライバ</b>

では、早速「第1シーズン 組込ソフトウエア開発概説」から始めます！

-------
<h1>第1シーズン 組込ソフトウエア開発概説</h1>

<h2>■コンピュータ、組込機器、マイコン...</h2>

最初はここで使う言葉の定義づけから入りましょう。

・コンピュータ
一言「コンピュータ」と言っても、人によっていろいろイメージが異なると思います。
ここでは、CPUと呼ばれるICチップのことを「コンピュータ」と呼ぶことにします。

・組込機器
そして、このコンピュータ（＝CPU）が内蔵されている電子機器のことを「組込機器」と呼ぶことにします。普段いろいろなところで触れている電気製品でコンピュータが入っていないものを探すのが難しいほど、今の世の中は組込機器であふれているのです。

・マイコン
当然、パソコンと組込機器ではコンピュータに要求される機能・性能が全く異なります。組込機器向けのコンピュータはサイズが小さく、消費電力が少なく、価格が安く...のようなパソコンと違う満たすべき条件があり、それを実現するため機能を限定し、クロックを落とし、メモリサイズを小さくし...のような特徴を持ちます。ここでは、こういった組込機器向けのコンピュータのことをマイクロコントローラ略して「マイコン」と呼ぶことにします。

・ファームウエア
このマイコン上で動く専用ソフトウエアが組込ソフトウエアですが、ここでは「ファームウエア」と呼びます。この場合の「ファーム」はfarm(農場)ではなくfirm(硬質な)から来ており、ハードウエア(hard)とソフトウエア(soft)の中間的な位置づけでこの名がついているようです。

-------
■今日の閑話
筆者がこの世界に入ったのは今から20年ほど前で、これまで某国民的ISDNルータなど、数多くの組込機器にネットワーク機能を入れる仕事をしてきました。その中で経験したちょっとしたトラブルやその原因調査方法、解決方法なんかも書いていこうと思います。よろしくお願いします！
UE4,5 C++でEditor Utility Widgetを作る。

# 1. Editor Moduleを作る(Riderの場合）
### Sourceフォルダ右クリック > Add > Unreal Module
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/b86a147c-3b30-3e93-a4c2-a2b7fd3208fd.png)
### New Unreal Module
- Module Name: **適当な名前**
- Module Type： **Editor**
- Loading Phase： **PosEngineInit**
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/b79d54b7-4537-124e-ea6a-feb58c24ff03.png)

# 2. Module名.Build.csの編集
### PrivateDependencyModuleNames.AddRangeに"UMG"を追加。
### Source内の他のモジュールを使う場合はそれも追加。（今回の例だとListView_CPP）
```c#:MyGameEditor.Build.cs
        PrivateDependencyModuleNames.AddRange(
            new string[]
            {
                "CoreUObject",
                "Engine",
                "Slate",
                "SlateCore",
                "UMG", 
                "ListView_CPP"
            }
        );
```
# 2. EditorUtilityWidgetの派生C++クラスの作成
### Content Browser右クリック > New C++ Class > EditorUtilityWidget
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/f92fdab3-b321-b596-c28f-acbf5148ec3b.png)
### Nameはお好きなように。その右のDropDownリストで先ほど作ったEditorModule(この例ではMyGameEditor(Editor))を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/8689a671-a3a9-eefb-da75-3ce497402c7d.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/def5dd9f-3076-219f-75be-9cb4725ce5ef.png)


:::note warn
ここ超重要
必ずEditorModuleを選択すること
:::
### 作成したクラスを適当に実装

# 3. EditorUtilityWidgetを作成し、その親に先ほど作ったC++クラスを指定する。
### Content Browser右クリック > Editor Utilities > Editor Utility Widgetで作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/42b2c8bc-d20c-a337-7c97-68e454ce26e8.png)
### 作成したWidgetを開いて、File > Reparent Blueprintを選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/1038bd2c-7b11-0b13-e85b-8a48bdd15a1c.png)
### 前項で作成したC++のEditorUtilityWidget派生クラスを選択。（今回の場合MyGameEditor_UtilityWidget）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/227f3143-0f16-d3ab-c895-062842c637d6.png)
### これでこのEditorUtilityWidgetが作成したC++のサブクラスになります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/4b94d93f-3290-5193-07e9-4ce468da02b1.png)

# ちゃんと右クリック > Run Editor Utility Widgetで起動できる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24726/239145dd-923b-7ff1-80bf-a694793db9e8.png)
align-なんたら、justify-なんたら

# 違いはなに？

接頭辞の意味は、どの方向に対して調整を行うか。
* align は、上下（垂直）方向の調整
* justify は、左右（水平）方向の調整

接尾辞の意味は どの要素に対して調整を行うか。
* selfは、指定した要素を調整
* itemsは、子要素を調整
* contentは、親要素を調整

<ruby>
justify<rt>左右方向</rt>
-<rt>に</rt>
content<rt>親要素</rt>
:<rt>を</rt>
center<rt>中央配置</rt>
;<rt>する</rt>
</ruby>

|値|align-self|align-items|align-content|justify-self|justify-items|justify-content|
|:-:|:-:|:-:|:-:|:-:|:-:|:-:|
|center|✔︎|✔︎|✔︎|✔︎|✔︎|✔︎|
|start (flex-start)|✔︎|✔︎|✔︎|✔︎|✔︎|✔︎|
|end (flex-end)|✔︎|✔︎|✔︎|✔︎|✔︎|✔︎|
|stretch|–|✔︎|✔︎|✔︎|✔︎|✔︎|
|left|–|–|–|✔︎|✔︎|✔︎|
|right|–|–|–|✔︎|✔︎|✔︎|
|auto|✔︎|–|–|✔︎|✔︎|–|
|space-between|–|–|✔︎|–|–|✔︎|
|space-around|–|–|✔︎|–|–|✔︎|
|space-evenly |–|–|✔︎|–|–|✔︎|
デザイナーが使用するGoogle Chromeの拡張機能


こんにちは。
オークファンでWebデザイナーとして働いている
@aucfan_hasebe です。
ここ最近寒い毎日が続いてますが、残念なことに1月2月もっと寒くなるはずなので皆さん気合いを入れて頑張っていきましょう！

今日はデザイナーおすすめのデザイン制作に使えるGoogle Chromeの拡張機能を紹介していこうと思います。



## デザイン制作時に使用できる機能


#### ■ColorZilla
https://chrome.google.com/webstore/detail/colorzilla/bhlhnicpbhignbdhedgjhgdocnmhomnp?hl=ja


定番の機能で、サイト上で使用してる色をワンクリックで判定してくれます。
個人的にはすごい便利で毎日使用してるものになります。

#### ■Site Palette
https://chrome.google.com/webstore/detail/site-palette/pekhihjiehdafocefoimckjpbkegknoh?hl=ja

Webサイトから、使用されているカラーを抽出し、カラーパレットを生成するChromeの機能拡張になります。
Photoshop, Illustrator, Sketch用のスウォッチも作成できるので、カラーバリエーションに迷ったとき等におすすめです。

#### ■WhatFont
https://chrome.google.com/webstore/detail/whatfont/jabopobgcpjmedljpbcaablpmlmfcogm?hl=ja

こちらはWebサイトの使用フォントを知りたい時にテキストにマウスオーバーすると、font-familyが表示されます。
デベロッパーツールでも良いのですがマウスオーバーするだけでサクッと知れるので便利です。


## コーディング時に使用できる機能

#### ■Design Mode
https://chrome.google.com/webstore/detail/design-mode/kcohlfofdggbjmbjoiopaddbjjblgnkl?hl=ja

設定するとページ内テキストを直接編集できる機能になります。
テキストの長さによってデザインの見え方が変わってしまう時のテスト用にサクッと使えるものになります。

#### ■HTML エラーチェッカー
https://chrome.google.com/webstore/detail/html%E3%82%A8%E3%83%A9%E3%83%BC%E3%83%81%E3%82%A7%E3%83%83%E3%82%AB%E3%83%BC/ohdllebchmmponnofchalfkegpjojcaf?hl=ja

表示中のページのHTMLが正しく書かれているのかを手軽に確認できる拡張機能になります。
デザイナー間でレビューをする前にまずはこちらのチェッカーでチェックするのがおすすめです。

#### ■PerfectPixel by WellDoneCode
https://chrome.google.com/webstore/detail/perfectpixel-by-welldonec/dkaagdgjmgdmbnecmcefdhjekcoceebi?hl=ja


デザインカンプとコーディングしたデータをブラウザ上でかさねて比較ができる機能になります。
デザインしたものと何か違って見える・・・という時に使用するとどこが違うのかすぐわかるので便利です。

#### ■CSS Pepper
https://chrome.google.com/webstore/detail/css-peeper/mbnbehikldjhnfehhnaidhjhoofhpehk

Webサイト内の要素をクリックすると、幅や高さ、padding、margin、font-family、色などを一気に調べることができる拡張機能。
他にも似たようなツールはいくつかあるのですがシンプルで使いやすいのがこちらになります。


## その他の便利機能

#### ■Pasty
https://chrome.google.com/webstore/detail/pasty/hdjihnnclpjhfdbbinmgoiehhoehhlgf?hl=ja

クリップボードのURLを一括で表示することができる拡張機能です。
例えば
https://www.netsea.jp/
https://www.google.com/
https://www.yahoo.co.jp/

を一気に開きたいという場合にまとめてURLをコピーして、Pastyをクリックすると全ページ開くことができます。
一般的なデザイナーさんが使う事は少ないかと思いますが、ECサイトの商品を一気に確認したい時等に重宝してます。

#### ■GoFullPage Full Page Screen Capture
https://chrome.google.com/webstore/detail/gofullpage-full-page-scre/fdpohaocaechififmbbbbbknoalclacl?hl=ja

Webページ全体のスクリーンショットを保存できます。
ブラウザに表示されてる部分だけや、自分で選んだピンポイントな部分だけのスクリーンショットも保存できるので
こちら一つ入れておくとデザインの参考にしたい時等に便利です。

#### ■TabCopy
https://chrome.google.com/webstore/detail/tabcopy/micdllihgoppmejpecmkilggmaagfdmb?hl=ja

開いている全てのタブのタイトルとURLを取得できます。
現在オークファンでの業務では使用してないのですが、前職でURL一覧を送る時にこちらが使えないと相当焦りました。
むしろデザイナーじゃなくディレクターさんやその他業務の際におすすめになります。

#### ■Lighthouse
https://chrome.google.com/webstore/detail/lighthouse/blipmdconlkpinefehnmjammfjpmpbjk?hl=ja

SEOチェックを行いたいページで使用するとページの採点をしてくれます。
デザイナーとして使用する機会は少ないとも思いますがページの読み込み速度を改善するために必要なCSSやJavaScriptの最適化についての解説もあるので
参考にすることができます。

<h2>最後に</h2>
いかがだったでしょうか？

もうちょっと技術的なことを書いた方が良いのでは・・・とも思ったのですが今回は時短になりそうな機能の紹介にしてみました！
昔の人が見たら「まあ！便利なものばかり使って！！手作業でやるから良いのよ！」と怒られそうな気もするのですが、ゆとり世代の中でも「究極のゆとり世代」に生まれた自分にとっては面倒な作業はどんどん便利にしてもらったほうがありがたいです。

作業を効率化できる部分は効率化してデザインを考える時間を多く確保できると楽しいデザイナーライフを送れると思います！

それではまた来年会いましょう〜
【W】wbr要素で長大語を区切る

Supercalifragilisticexpialidociousの折返し位置指定をしよう、というタグ

## 使い方

```html
Super<wbr>cali<wbr>fragilistic<wbr>expiali<wbr>docious
```

## 効果

幅が狭いなどして1単語が同じ行に収まらない場合などに、wbrがあるところで改行してそれを回避しようとします。

```txt:ちょっと幅が足りないときとかはこうなる
Supercalifragilistic
expialidocious
```

```txt:最小幅でこうなる可能性はある
Super
cali
fragilistic
expiali
docious
```

とはいえ、極端に幅が狭いとこれでも対応しきれなくなります。
特に日本語なら`word-break: break-all;`でいい。
非同期処理サンプルプログラム(JavaScript)

JavaScriptで非同期処理のサンプルプログラムを実装しました

```HTML
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>非同期処理テスト6</title>
  <style>
    #test1{
      width:300px;
      font-size:30px;
      color:#0E8;
      background-color:#B0D;
    }
  </style>
</head>
<body>
  <div id="test1"></div>
  
  <script>
    
    // 非同期処理で画面に表示する名前と表示時間設定関数
    const test1 = document.getElementById('test1');
    func = async () => {
      await disp("秋元真夏",0);
      await disp("白石麻衣",1000);
      await disp("松村沙友理",700);
      await disp("生田絵梨花",900);
      await disp("",700);
      await disp("齋藤飛鳥",2000);
      await disp("",1000);


    }
    //ブラウザに名前を表示する関数
    disp = (name,time) => {
      return new Promise(resolve => {
        setTimeout(() => {
          test1.textContent = name;
          resolve();
        },time);
      });
    }
    //関数の呼び出し
    func();
    

  </script>
</body>
</html>
```

awaitを使って実装しました。
MySQL 大文字と小文字について

:::note info
この記事は[miriwoお一人様 Advent Calendar 2022](https://qiita.com/advent-calendar/2022/miriwo)の20日目の記事です
:::

## 概要

- MySQLの大文字と小文字の扱いについて簡単にまとめる

## 内容

### カラムの値のwhereによる絞り込み

下記カラムの値は絞り込み時、大文字小文字は考慮されない。（考慮される様にSQLを記載することはできる、バイナリ比較まで含めれば良いはず）

- CHAR
- VARCHAR
- TEXT

下記カラムの値は絞り込み時、大文字小文字は考慮される。

- BINARY
- VARBINARY
- BLOB

なので下記のようなusersテーブルのに`select * from users where name = 'test';`というSQL句を実行した時に3レコードすべてがヒットする。（nameカラムはvarchar 255）

| id | name |
| --- | --- |
| 1 | test |
| 2 | TEST |
| 3 | TeSt |

### テーブル名やDB名

テーブル名やDB名の大文字小文字を考慮しないようにするにはmysqldの起動時に`lower_case_table_names`の値で設定する事ができる。
`lower_case_table_names`はMySQLサーバーの初期化時のみ設定できる。初期化後のlower_case_table_namesの値の設定変更は禁止されているらしいので注意すること。

| 状態 | 解説 |
| --- | --- |
| lower_case_table_names=0 | 大文字と小文字が区別される<br>（Windows、Macでこの設定にしてはだめ） |
| lower_case_table_names=1 | 大文字と小文字が区別されない<br>各名前は小文字でディスクに保存される。なので show tableした時は大文字で作成したテーブルも小文字で表示される |
| lower_case_table_names=2 | 大文字と小文字が区別されない<br>大文字で作成したテーブル名は大文字で、小文字で作成したテーブル名は小文字でディスクに保存される。しかしshow tableした時はすべて小文字で表示される |

ちなみに`lower_case_table_names`の値は下記SQLを実行することで現在の設定値を確認する事ができる。

```sql
show variables where variable_name='lower_case_table_names';
```
## 参考文献

https://dev.mysql.com/doc/refman/8.0/ja/identifier-case-sensitivity.html

https://dev.mysql.com/doc/refman/8.0/ja/case-sensitivity.html