OmniAICreator/Qiita-1.07M huggingface dataset:
AP Iとは？

# はじめに
毎週1本様々な技術に関する記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)

# APIとは
API（Application Programming Interface）とは、`ソフトウェアが他のアプリやモジュールと対話するためのインターフェース`で、プログラムが互いに通信し、情報を共有する方法を提供します。

# APIの主な特徴
- 機能提供
APIは、__他のプログラムが特定の機能やサービスにアクセスできるようにします。__ 例えば、ウェブAPIは、ウェブサービスを介してデータを取得したり、操作したりするためのAPIです。
- データ共有
__ソフトウェア間でデータを共有__ することができます。これにより、情報を効果的に転送し、異なるアプリケーション間で連携できます。
- 拡張性とカスタマイズ
アプリ開発者は、APIを介して __他の開発者が自分のアプリケーションを拡張またはカスタマイズできる__ ようにすることができます。これにより、エコシステムを拡大し、新しい機能を追加できます。

# APIの種類
APIはさまざまな種類が存在します。以下にそのいくつかを紹介します。
- ウェブAPI
__インターネットを通じてアクセスできるAPI__ で、ウェブサービスとの通信に使用されます。例えば、InstagramやLINEのようなソーシャルメディアプラットフォームのAPIは、アプリがユーザーデータを取得したり投稿を共有したりするのに使用されます。
- ライブラリAPI
ソフトウェアライブラリやフレームワークが提供するAPIで、特定のタスクを簡素化したり、__既存のコードを再利用__ したりするのに役立ちます。
- オペレーティングシステムAPI
オペレーティングシステム（OS）が提供するAPIで、アプリがハードウェアやシステム機能にアクセスするのに使用されます。

# APIと似た言葉(おまけ)
APIとよく混同される、「SDK」や「ライブラリ」とAPIとの違いについて紹介します。

### ◾️SDK
SDK（Software Development Kit）とは、ソフトウェア開発をサポートするパッケージのことです。
APIはプログラム間のコミュニケーションを可能にするためのルールや方法を提供し、SDKは特定のプラットフォームやサービス向けの開発リソースを提供する包括的なツールセットです。

### ◾️プラグイン
プラグインとは、既存のアプリに追加の機能や拡張機能を提供するためのソフトウェアです。

# 終わりに
APIは、ソフトウェア開発において不可欠なツールであり、異なるアプリやサービスが協力してデジタルエコシステムを築くための基盤です。開発者にとって、APIの理解と適切な利用は、非常に重要な要素となります。

最後までお付き合いくださりありがとうございました。
せんせー、組織培養肉ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、組織培養肉ってなに？

# 組織培養肉とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## 組織培養肉とは何でしょうか？

組織培養肉は、動物の細胞をラボの中で育てて作られる新しいタイプの肉です。これは、実際の動物を育てる代わりに、少量の動物の細胞から大量の肉を生産する方法です。

## どのように作られるのでしょうか？

まず、動物の筋肉組織から細胞を取り出します。そして、それらの細胞を特殊な栄養溶液の中で培養して、細胞が増えるのを助けます。このプロセスで、細胞は成長し、肉の塊を形成します。

## どうしてそれがすばらしいのでしょうか？

組織培養肉は環境への影響が少なく、動物を実際には殺さずに肉を生産する方法を提供します。これにより、食品生産の持続可能性を向上させることが可能になります。

## どのような用途がありますか？

組織培養肉は、通常の肉と同様に、さまざまな料理や製品の製造に使用することができます。将来的には、これが更なる食品安全と持続可能な食品生産方法を提供する重要な工具になり得ます。

# まとめ

組織培養肉は、ラボ環境で動物の細胞を培養することにより作られる新しいタイプの肉です。この方法は環境に優しく、持続可能な食品生産の未来を開く可能性があります。また、動物を殺さないという利点もあります。
せんせー、クアンタムドットディスプレイってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、クアンタムドットディスプレイってなに？

# クアンタムドットディスプレイとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## クアンタムドットディスプレイとは何でしょうか？

クアンタムドットディスプレイは、非常に小さなナノサイズの粒子、いわゆる「クアンタムドット」を使用して色を生成する最新のディスプレイ技術です。この技術は、テレビやモニター、スマートフォンの画面をより鮮明で明るくするために使われます。

## どのように機能しますか？

クアンタムドットは、特定の波長の光を放射する能力を持っています。ディスプレイはこれを利用して、バックライトからの光をクアンタムドット層に通すことで特定の色を作り出します。この技術により、広い色域と高い輝度が実現されます。

## なぜそれがすばらしいのでしょうか？

クアンタムドットディスプレイは、従来のディスプレイ技術に比べて色の再現性が高く、エネルギー効率が良いという利点があります。これにより、見る人々にとって非常に鮮明でリアルな色彩表現を提供することが可能になります。

## どのような用途に使われているのでしょうか？

現在、高品質のテレビやモニター、スマートフォンなどのディスプレイにクアンタムドット技術が利用されています。特に高解像度の映像を求めるプロフェッショナルな用途や、映画鑑賞、ゲームなどにおいてその性能を発揮します。

# まとめ

クアンタムドットディスプレイは、クアンタムドットという特殊なナノ粒子を利用することで、色の再現性が高く、エネルギー効率が良い画面を実現しています。これにより、我々は非常に高品質な映像体験を得ることができるのです。
Gitで設定ファイルが変更ツリーに表示されるのを防ぐ

接続文字列などが書かれた設定ファイル(config.json等)が変更ツリーに上がってきてしまい、誤ってコミットしてしまうことがありました。
こういった事故を防ぐために、変更の追跡をしないようにするコマンドを記載します。

### 変更を追跡しないようにする
変更ツリーに表示されなくなり、変更を加えてもコミットできなくなります。
``` shell
git update-index --assume-unchanged .\appsettings.json
```

### 変更を追跡するようにする
変更ツリーに表示されるようになり、コミットできるようになります。
``` shell
git update-index --no-assume-unchanged .\appsettings.json
```
せんせー、ミリ波イメージングってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、ミリ波イメージングってなに？

# ミリ波イメージングとは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## ミリ波イメージングとは何でしょうか？

ミリ波イメージングは、ミリ波と呼ばれる非常に高い周波数の電磁波を用いたイメージング技術のことです。この技術は、ボディスキャナーとして空港での安全検査などに使用されることが多いです。

## どのように動作するのでしょうか？

この技術は、ミリ波レーダーを使用して物体や人の表面から反射するミリ波を捉えます。そして、これらのデータから画像を生成します。このため、被写体の形やサイズ、材料の性質などを視覚的に捉えることが可能です。

## どうしてこれは重要なのでしょうか？

ミリ波イメージングは非侵襲的な検査方法であり、特定の環境やアプリケーションでの安全を確保する上で非常に重要です。例えば、空港のセキュリティチェックで、隠された物や危険な物を検出するのに非常に有用です。

## どのような用途がありますか？

この技術は主にセキュリティと保安の分野で利用されており、空港での人体スキャンや建物のセキュリティスキャンなどに使用されています。また、ミリ波イメージングは医療分野でも研究されており、将来的には新しい診断ツールとして利用される可能性があります。

# まとめ

ミリ波イメージングは高周波の電磁波を使用したイメージング技術であり、安全保障や診断ツールとしての潜在的な用途があります。非侵襲的な方法で詳細な画像を提供できるため、多くの分野での利用が期待されています。
Streamlitのチャットbot UIを試してみる

久々にStreamlitのマニュアルを見たらチャットbotのインタフェースがサポートされていました(気づくの遅い)。

https://docs.streamlit.io/knowledge-base/tutorials/build-conversational-apps

こちらの画面を差し替えます。DatabricksクラスターでStreamlitをサービングしています。

https://qiita.com/taka_yayoi/items/a42691495a890fe81238

```py:client_streamlit.py
import streamlit as st 
import numpy as np 
import json
import requests

st.title('Databricks Q&A bot')
#st.header('Databricks Q&A bot')

def generate_answer(question):
  # Driver Proxyと異なるクラスター、ローカルからDriver Proxyにアクセスする際にはパーソナルアクセストークンを設定してください
  token = "" 
  url = "http://127.0.0.1:7777/"

  headers = {
      "Content-Type": "application/json",
      "Authentication": f"Bearer {token}"
  }
  data = {
    "prompt": question
  }

  response = requests.post(url, headers=headers, data=json.dumps(data))
  if response.status_code != 200:
    raise Exception(
       f"Request failed with status {response.status_code}, {response.text}"
    )
  
  response_json = response.json()
  return response_json


if "messages" not in st.session_state:
    st.session_state.messages = []

# アプリの再実行の際に履歴のチャットメッセージを表示
for message in st.session_state.messages:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# ユーザー入力に対する反応
if prompt := st.chat_input("Databricksに関して何を知りたいですか？"):
    # チャットメッセージコンテナにユーザーメッセージを表示
    st.chat_message("user").markdown(prompt)
    # チャット履歴にユーザーメッセージを追加
    st.session_state.messages.append({"role": "user", "content": prompt})

    with st.spinner('回答を生成中...'):
      bot_response = generate_answer(prompt)
      answer = bot_response["answer"]
      source = bot_response["source"]

      response = f"""{answer} 

**ソース:** {source}"""

    # チャットメッセージコンテナにアシスタントのレスポンスを表示
    with st.chat_message("assistant"):
      st.markdown(response)

    # チャット履歴にアシスタントのレスポンスを追加
    st.session_state.messages.append({"role": "assistant", "content": response})
```

おおー、いい感じです。次はstreamingを実装しよう。
![Screenshot 2023-09-11 at 19.56.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4c992791-fb95-7645-b6df-0127b15cf96e.png)


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

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


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
2週間弱でITIL4foundation試験に受かる方法

本記事では、ITIL4foundationに2週間で合格した勉強法を紹介する。

# 著者のスペック
試験の計画を立てる際、本記事のような資格対策系の記事は参考にされると考えた。
しかし、試験に合格するまでの時間は試験受講前の人間のスペックに大きく左右される。
したがって、本記事でも著者のスペックを紹介したいと思う。

- 偏差値50前後の現代社会学専攻
- IT業界（SES）で営業として1年の勤務経験
- 基本情報技術者試験に落ちた経験あり←更新

# 学習期間
- 学習期間は8月17日から9月3日の17日間
- 総学習時間は17時間程度

# 2週間弱で試験に合格する4つのステップ
ここからは、試験に合格した勉強法を4つのステップに分けて説明する。

## 1 全体像を抑える
いきなり詳細情報に触れると理解に苦しむため、まずは全体像を掴むことを推奨する。
私が全体像を掴むために参照したのは「ITILはじめの一歩」という書籍である。
参考書で全体像を掴むのも良いが、難解に書かれていることが多い。そのため、上記で推奨した簡単に書かれた本を読むと良い。
なお、ステップ1では用語を暗記する必要はないことは強調しておきたい。

## 2 過去問を1回解く
全体像を掴んだ後は過去問に取り掛かってほしい。
何をどの粒度で暗記する必要があるかを知るのが目的である。
したがって、点数が取れなくてもへこむ必要はない。ちなみに筆者の初回の得点は4割未満であった。

### 使用した過去問
過去問は「IT Service Management教科書 ITIL 4ファンデーション」の過去問を使用した。
巷で有名なクラムメディアを利用する手もあったが、高価であるのと解説がないため今回は使用はしていない。

## 3 参考書を読む
ステップ3でようやく参考書が登場する。
ここにいる頃には、過去問が頭の中にある状態なので、参考書を読み進めると「この単語の定義が過去問で問われていたからしっかり覚えよう」といった具合にインプットができるため非常に効果的である。
また、ここで参考書を読む理由は、情報をつなぎ合わせるという意味合いもある。
過去問を解いて感じた方もいるかもしれないが、一問一問が詳細情報であるため頭の中で情報が散乱になってしまいがちである。
そこで体系的にまとまった参考書を読むことで、バラバラな情報をまとめることができて理解度がより深まる。


## 4 過去問で80%を取れるまで周回する
参考書を読み情報を繋ぎ合わせたら、80%を取れるまで過去問に取り組む。
ステップ3を踏んでいることで、過去問を解くときの理解度が倍増していると感じているはずだ。

## おわりに
以上がITILを合格するために取り組んだ勉強法である。是非、参考にしてほしい。
せんせー、無線電力伝送ってなに？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/2c47de5a-d81a-78f9-53c1-4d31d8398c36.png)

キーンコーンカーンコーン...
授業が始まります

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/be1492ca-910f-2708-d0fa-8fcfcf14af73.png)

せんせー、無線電力伝送ってなに？

# 無線電力伝送とは

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3194265/da229491-9c49-fb7a-a542-417180e256a7.png)

## 無線電力伝送とは何でしょうか？

無線電力伝送とは、物理的な接続なしに電力をある場所から別の場所に送る技術のことです。これにより、ケーブルやワイヤーなどを使わずにデバイスを充電したり、動力を供給することが可能になります。

## どのように機能しますか？

無線電力伝送は、主に電磁波や共振を利用して電力を送信します。送電側と受電側の間に特殊なコイルを用いて、特定の距離で電力を無線で伝送する技術が一般的に利用されています。

## どのような利点がありますか？

無線電力伝送の利点としては、ケーブルが不要となり、設置が簡単であるという点が挙げられます。また、装置のデザインをより自由に行えるようになるとともに、ケーブルのトラブルや接触不良による問題を避けることができます。

## どんな用途に使用されていますか？

無線電力伝送はスマートフォンのワイヤレス充電や電動歯ブラシ、また未来的な観点からは電動車の充電インフラストラクチャの開発にも利用されています。また、医療機器の充電や電源供給にも利用される可能性があります。

# まとめ

無線電力伝送は、電力を物理的な接続なしに送る革新的な技術です。これにより、デバイスの充電や動力供給がより簡単かつ便利に行えるようになり、さまざまなアプリケーションで利用可能です。この技術の発展によって、未来のエネルギーインフラストラクチャが大きく変わるかもしれません。
Javaで「メソッドのオーバーライド」の動作を確認してみた

# 概要

Javaで「メソッドのオーバーライド」の動作を確認してみました。以下のページを参考にしました。

https://www.javadrive.jp/start/extends/index5.html

# 実装

以下のファイルを作成しました。
```CTest17.java
class CTest17{
  public static void main(String args[]){
    C c = new C();
    c.disp();
  }
}

class A{
  public void disp(){
    System.out.println("電化製品です");
  }
}

class B extends A{
  public void disp(){
    System.out.println("エアコンです");
    super.disp();
  }
}

class C extends B{
  public void disp(){
    System.out.println("三菱製です");
    super.disp();
  }
}
```

以下のコマンドを実行しました。
```
$ javac CTest17.java 
$ java CTest17 
三菱製です
エアコンです
電化製品です
```

# まとめ
何かの役に立てばと。
Laravel 10 で簡単な API を作成

## プロジェクトの作成

```bash
laravel new api_test
cd api_test
```

## routes/api.php の編集

```php:api.php
<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "api" middleware group. Make something great!
|
*/

Route::middleware('auth:sanctum')->get('/user', function (Request $request) {
    return $request->user();
});

Route::get('/aa', function () {
    return [70,30];
});

Route::get('/bb', function () {
    return [5,4,8];
});

Route::get('/cc', function () {
    return [40,20,8,9,5];
});
```

作成したルートの確認

```text
$ php artisan route:list

  GET|HEAD   / ............................................................... 
  POST       _ignition/execute-solution ignition.executeSolution › Spatie\Lar…
  GET|HEAD   _ignition/health-check ignition.healthCheck › Spatie\LaravelIgni…
  POST       _ignition/update-config ignition.updateConfig › Spatie\LaravelIg…
  GET|HEAD   api/aa .......................................................... 
  GET|HEAD   api/bb .......................................................... 
  GET|HEAD   api/cc .......................................................... 
  GET|HEAD   api/user ........................................................ 
  GET|HEAD   sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › Csrf…

                                                            Showing [9] routes
```

## サーバーの起動

```bash
php artisan serve --host 0.0.0.0
```

## クライアントでアクセス

>URL に api が入ります。

```bash
http http://localhost:8000/api/aa
```

実行結果

```text
$ http http://localhost:8000/api/aa
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Cache-Control: no-cache, private
Connection: close
Content-Type: application/json
Date: Mon, 11 Sep 2023 10:28:24 GMT
Date: Mon, 11 Sep 2023 10:28:24 GMT
Host: localhost:8000
X-Powered-By: PHP/8.1.12-1ubuntu4.3
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59

[
    70,
    30
]
```

同様に

```bash
http http://localhost:8000/api/bb
```

```bash
http http://localhost:8000/api/cc
```

## 確認したバージョン

```text
$ uname -a
Linux shimizu 6.2.0-32-generic #32-Ubuntu SMP PREEMPT_DYNAMIC Mon Aug 14 10:03:50 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux

$ php --version
PHP 8.1.12-1ubuntu4.3 (cli) (built: Aug 17 2023 17:37:48) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.1.12, Copyright (c) Zend Technologies
    with Zend OPcache v8.1.12-1ubuntu4.3, Copyright (c), by Zend Technologies

$ php artisan --version
Laravel Framework 10.22.0
```
【dev.to】アイスブレイカーのバッジを実装したよ

[dev.to](https://dev.to/)は、客を集めコミュニティを盛り上げるために様々な施策を行っています。
[先日そのいくつかを紹介しました](https://qiita.com/rana_kualu/items/1c8908e6ca04d2714d73)が、今回はさらに別の施策を紹介します。

そのユーザがdev.to上でどれだけ活躍しているかを一目で表す便利な勲章である、バッジという機能があります。
たとえば[The DEV Team](https://dev.to/thepracticaldev)であれば7年以上活動している、16週間毎週投稿した、[WeCoded 2023](https://dev.to/t/wecoded)に参加した、といったバッジをゲットしています。
バッジをたくさん増やすのもよし、あるいは[所有者が5名しか存在しないバッジ](https://dev.to/devteam/github-dev-2023-hackathon-winners-announced-236o)であれば技術の裏付けにもなるし自慢もしたくなったりするでしょう。

バッジと同様のシステムはGitHubや、ゲーム業界などにも広く存在しています。
この手の勲章は当然ながら大昔から存在していますが、システムとして初めて整備したのはXBOXの実績で、そこからSteamや各種コミュニティ等に広がっていったんじゃないかと思っているのですが実際はどこが起源なのでしょうかね。
そういえばどうでもいいけど実績は10万以上あります。

以下は[dev.to](https://dev.to/)スタッフによる新たなバッジを追加した記事、[Announcing the Icebreaker Badge! 🧊🔨](https://dev.to/devteam/announcing-the-icebreaker-badge-20k3)の紹介です。


# Announcing the Icebreaker Badge! 🧊🔨

今週の新しい追加バッジはこれだ🙌

## Introducing the Icebreaker Badge!

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/8ffe05b7-a8a3-f003-0d79-4d77e0de0e4c.png)

このバッジは、他者の投稿に最初のコメントを行い、[氷を砕く](https://www.dictionary.com/browse/break--the--ice)きっかけとなり、ディスカッションを盛り上げた人に贈られます。

## How it works

このバッジを獲得する最善の方法は、思慮深く素敵なコメントを真っ先に行うことです。
ただ単に「ナイスポスト！」とコメントすることも歓迎されることですが、このバッジを獲得するためには、もっと考えを込めたコメントを行う必要があります。

最後に、自分の投稿へのコメントはこのバッジの対象外となります。

## Why did we create this badge?

何故このバッジを作ったのか？

[ウェルカムバッジ](https://dev.to/devteam/introducing-the-warm-welcome-badge-4hnh)と同じく、我々はこのバッジを、親切で温かく、誰でもウェルカムなコミュニティを作ってくれている人々に報いるために作成しました。
投稿に最初にコメントすることで、他の人たちも続いて自分の考えを共有しやすくなります。
コメントは、コミュニティを形成するうえで欠かせないものです。
記事へのアイデアの分かち合い、互いの交流が存在しなければ、ここはただの一方通行メディアに過ぎなくなってしまいます。
従って我々は、氷を砕き、会話を作るきっかけになってくれる全ての人々に報いたいと考えているのです。

我々はこのバッジをとても大事に思っていますし、みなさんもそうであることを願っています。
もしバッジの新たなアイデアや、報酬に値すると思う行動があれば、是非[ご意見をお聞かせください](https://dev.to/devteam/explore-our-world-of-badges-influence-the-next-addition-1fnf)。



# コメント欄

「ナイスポスト！」「←最初のコメントがこれとはグッド🤣」「誰かがやらねばならなかった🙂」「今回だけは許す！」
「いいバッジ。僕のコレクションに入れたいね。」
「アイスピックを用意してこなくちゃ。」
「Toastmastersに参加したことがあるから、このバッジが非常に有益であることがわかる。」
「みんなコメントありがとう！最初のアイスブレイカーバッジを7人に贈ったよ」「ありがとうございます！」
「バッジを獲得するために従業員を雇ったよ」

![02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/18df9ec6-bad2-3f06-19fb-1889006d6d92.gif)

# 感想

dev.toはとにかくコメントを重視しており、このアイスブレイカーバッジもその一環となります。
これまでは[間接的に盛り上げる施策](https://qiita.com/rana_kualu/items/1c8908e6ca04d2714d73)が多かったように思えますが、今回のこれは思いっきり直接的ですね。
記事にもあるとおり、最初に1件でもコメントがあると、他の人もコメントしやすくなるということは実際にあります。
そしてコメントが集まるということは人も多いように見えるということであり、人の多いところにはますます人が集まります。

実際、dev.toではある程度の人気記事は数十のコメントが付くことが普通ですからね。
[週間ランキング](https://dev.to/top/week)以上に載るような記事では、コメントがないほうが珍しいくらいです。

この現状は、アイスブレイカーバッジだけではなく、バッジを含めた様々な施策を継続的に行ってきた結果と言えるでしょう。


ところで実は[Qiitaにもバッジがあります](https://qiita.com/Qiita/items/563a6ea111709a03fbea#contribution%E3%83%90%E3%83%83%E3%82%B8%E3%82%92%E8%BF%BD%E5%8A%A0%E3%81%97%E3%81%BE%E3%81%97%E3%81%9F)。

![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/26088/9ffc48a0-779a-56d4-45bc-b01d0bba8f6e.png)

ところがこのバッジ、自分しか見ることができません。
デフォルト非公開というならともかく、公開する手段が一切ありません。
どうやら[2年近く前から存在する](https://qiita.com/kaizen_nagoya/items/72f36a2af777f709c375)みたいですが、公開できないせいで現状では全く意味のない機能です。
いったい何がしたいんだこれ。
情報収集ソース

私が技術に関する情報収集（キャッチアップ）をするときに参照しているWebサイトをまとめました。

### コミュニティ系
- [Qiita](https://qiita.com/)
- [Zenn｜エンジニアのための情報共有コミュニティ](https://zenn.dev/)

### 最新技術系
- [Publickey － Enterprise IT × Cloud Computing × Web Technology / Blog](https://www.publickey1.jp/)
- [OSDN Magazine -- オープンソースの話題満載](https://mag.osdn.jp/)
- [InfoQ: ソフトウェア開発の最新情報、トレンドと事例紹介](https://www.infoq.com/jp/)

### 出版社系
- [CodeZine（コードジン）](https://codezine.jp/)
- [gihyo.jp](https://gihyo.jp/)

### メディア系
- [IT製品／サービスの導入・購買を支援する「TechTargetジャパン」](https://techtarget.itmedia.co.jp/)
- [ITエキスパートのための問題解決メディア - ＠IT](https://atmarkit.itmedia.co.jp/)
- [Cloud USER by ITmedia NEWS](https://www.itmedia.co.jp/news/subtop/clouduser/)
- [PC、Mac、最新デバイスまで網羅するパソコン総合情報メディア - ITmedia PC USER](https://www.itmedia.co.jp/pcuser/)
- [ビジネス+IT](https://www.sbbit.jp/)
- [Ledge.ai | AI（人工知能）関連メディア](https://ledge.ai/)
- [製造業のための製品・サービス情報サイト - TechFactory](https://techfactory.itmedia.co.jp/)
- [世界のエレクトロニクス技術の最新動向がわかる - EE Times Japan](https://eetimes.itmedia.co.jp/)
- [Think IT（シンクイット） | オープンソース技術の実践活用メディア](https://thinkit.co.jp/)
- [ICS MEDIA - ウェブデザイナー/フロントエンジニアの必読メディア](https://ics.media/)
- [業務効率化ガイド｜業務効率化のノウハウを発信するメディア – 業務効率化のノウハウを発信するメディア](https://www.stock-app.info/media/)
- [TechRepublic: News, Tips & Advice for Technology Professionals](https://www.techrepublic.com/)
- [TECH+総合トップ | TECH+（テックプラス）](https://news.mynavi.jp/techplus/)
- [ログミーTech - 技術のトレンドがわかるエンジニア向けメディア](https://logmi.jp/tech)
- [GameBusiness.jp](https://www.gamebusiness.jp/)

### キャリア系
- [エンジニアtype | 技術者のキャリアを考えるWebマガジン](https://type.jp/et/feature/)
- [レバテックラボ（レバテックLAB） | レバテックラボ｜キャリアと技術の可能性が見つかるメディア](https://levtech.jp/media/)
- [特集一覧 | ハイスキルなエンジニアのプレミアム転職Findy](https://findy-code.io/pick-up)

### 企業ブログ系
- [さくらのナレッジ | 「知る」「学ぶ」「つくる」を育てるITエンジニアのためのメディア](https://knowledge.sakura.ad.jp/)
- [クラスメソッド発「やってみた」系技術メディア | DevelopersIO](https://dev.classmethod.jp/)
- [Cygames Engineers' Blog](https://tech.cygames.co.jp/)
- [IIJ Engineers Blog](https://eng-blog.iij.ad.jp/)
- [Experiments with Google](https://experiments.withgoogle.com/)
- [サイバーセキュリティ情報局 | サイバーセキュリティ情報局](https://eset-info.canon-its.jp/malware_info/)
- [カゴヤのサーバー研究室｜レンタルサーバー屋さんのノウハウを大公開](https://www.kagoya.jp/howto/)
- [コラム一覧 | ITフリーランスエンジニア案件ならA-STAR（エースター）](https://agency-star.co.jp/column/)
- [その他お役立ちコンテンツ一覧 | テクフリ](https://freelance.techcareer.jp/articles/wp/)
- [MonotaRO Tech Blog](https://tech-blog.monotaro.com/)
- [NotePM ブログ](https://notepm.jp/blog)

### 個人ブログ系
- [スタバのブログ庫](https://sbucks-blog.com/)
- [ソフトアンテナ | PCやMacの性能を100%発揮](https://softantenna.com/blog/)

### ホワイトペーパー
- [ホワイトペーパー ダウンロードセンター | IT製品資料・技術資料ダウンロードサイト](https://wp.techtarget.itmedia.co.jp/)
ベテランSEの事件簿　～スケジュールが遅延してくるとついついやってしまうアレ～

# プロローグ
プロジェクトが繫忙期を迎え、リソースが足りないとスケジュールが遅延し始めます。

スケジュールをリカバリするため、急遽アクション会議が開かれ
**あること**を実行することが決まりました。

しかしながら、実行した結果は芳しくなく、むしろさらにスケジュールは遅れていったのです。

# 事件内容
私はあるプロジェクトにおいて5名ほどの開発チームのリーダーを任されていました。

開発する対象のシステムは見積もり段階よりも機能数が多く、また開発難易度の高いものが多いため
徐々にスケジュールが遅延し始めていました。

状況を察知したプロジェクトマネージャーが私に声をかけ、
スケジュール遅延の原因を聞いてきます。

私は正直に、開発ボリュームが多く、また仕様が複雑で時間がかかっていますと答えました。

「分かった。対策を考える。」
と言ってプロジェクトマネージャーはどこかに行ってしまいました。
数時間後、偉い人たちが集められ、緊急のアクション会議が開かれることになったようです。


会議はすぐに終わり、再度プロジェクトマネージャーに呼ばれました。
「お前のチームの遅延をリカバリするために来週からメンバーを3名追加することに決まったから」

「今、人を増やしても改善しませんよ？」と話してもあとの祭り。
すでに追加メンバーが決定していることをプロジェクトマネージャーの口から告げられました。。

私は遅延がより膨らむ覚悟をしたのでした。

# 事件その後
私のチームに3名の新規メンバーが入ってきました。
全員、エンジニア経験もあり人柄も問題ありません。やる気もあります。

新規メンバーに対しては、プロジェクトの説明会を行ったり資料の読み込んでもらったりします。
不明点に対して既存メンバーが回答する必要もあります。

すでに遅延しているスケジュールの作業に加えて、新規メンバーの受け入れという作業が加わったのです。

本来やるべきプロジェクト作業ができず、さらに遅延していく状況。。。
思うように改善されず頭を悩ますプロジェクトマネージャー。

対策として安易に実施したプロジェクトメンバーの追加によって、
プロジェクトは最悪な方向に進んでいったのでした。

# エピローグ（教訓）
このエピソード、システム開発現場で働いたことがある方なら一度は遭遇したことがある状況だと思います。

「遅れているソフトウェアプロジェクトへの要員追加は、プロジェクトをさらに遅らせるだけである」
という**ブルックスの法則**があるように、本当によくあることなのです。

ブルックスの法則の成り立つ理由は以下の通りらしいです。

```
１．新たに投入された開発者が生産性の向上に貢献するまでには、時間がかかる。
ソフトウェアプロジェクトは、複雑な作業である。また、新たにプロジェクトに参加した人は、
仕事に取りかかる前に、まず開発の現状や設計の詳細などを理解しなければならない。
つまり、新たに人員を追加するには、その人員を教育するために、リソースを割かなければならないのである。
したがって、人員の増加がチームの生産性に与える効果は、短期的にはマイナスになる。
また、プロジェクトに慣れない間はミスを犯しやすいので、新たなバグが挿入されることが多くなり、
その結果、プロジェクトがさらに遅れる可能性もある。

２．人員の投下は、チーム内のコミュニケーションコストを増大させる。
プロジェクトを進めるうえで、プロジェクトチームは、協力して同じ課題に取り組む必要がある。
しかし、これを実現するには、調整のためのコストがかかる。一般に、n人が協調して仕事を進めるためには、
n(n-1)のコミュニケーションチャンネルを調整する必要がある。したがって、プロジェクトの人員に対して
コミュニケーションコストは、n^2のオーダーで増加することになる。
単純にいえば、開発メンバーを2倍に増やしたチームは、
それに伴って4倍のコミュニケーションコストを負担するのである。

３．タスクの分解可能性には限界がある。
ホテルの部屋の清掃のような分解可能性の高いタスクであれば、
人員投入によってタスク全体の所要時間は短くなる（作業者同士の干渉が起きないかぎり）。
しかし、分解可能性の低いタスクもある。1人の妊婦が9か月で赤ちゃんを出産できても、
9人の妊婦が1ヶ月で赤ちゃんを出産することはできないのである。
```
(引用元) https://ja.wikipedia.org/wiki/%E3%83%96%E3%83%AB%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E6%B3%95%E5%89%87

これを読むと、「当たり前だよな」と思う人がほとんどなのではないでしょうか。
でも実際の現場ではなぜか、日常茶飯事で起きているのです。不思議ですね。

きっと、焦っているプロジェクトマネージャーは
『何か対策を打たないと！』
『このプロジェクトにはブルックスの法則は当てはまらない（から人を入れれば何とかなる！）』
と考えてしまうのだと想像します。

遅延しないことが一番なので、受注時の見積もりや要件定義で自分の首を絞めないようにすることは言わずもがなです。

もし遅延に対して手を打つなら素早い行動が一番です。
そうすればメンバーの教育の時間も取れますので・・・

というわけで『スケジュールが遅延してくるとついついやってしまうアレ』とはプロジェクトメンバーの安易な追加のことでした。

**プロジェクトメンバーの追加は慎重に。**
React：開始/終了時刻が相互に影響し合う選択式メニューの作成

## 概要
超初心者エンジニアが0:00～24:00の間で開始時刻＜終了時刻になるような選択式メニューの作り方を考えました。
`<input type="time">`などは時計マークから詳細設定が可能になってしまうので、手動で選択肢を設定しようと思った結果、このような方法にしました。

## 前提
ReactのuseState,useEffectを用いて管理します。
また、React UI ライブラリ[Antdesign](https://ant.design/)のSelectメニューを使用しました。

## Reactコンポーネント
returnに入る内容です。私はそれぞれをFormItemとして使いました。
```tsx
// 開始時刻の選択
<Select
    onChange={handleStartChange}
    options={startTimeOption} 
/>

// 終了時刻の選択
<Select
    onChange={handleEndChange}
    options={endTimeOption}
/>
```


## 使用するState
AntdesignのSelectで表示する選択肢は`{ value: number; label: string; }[]`形式でないといけないらしいです。
```tsx
// 開始時刻の選択肢は0～startTimeMax
const [startTimeMax, setStartTimeMax] = useState<number>(23)
const [startTimeOption, setStartTimeOption] = useState<{ value: number; label: string; }[]>([])

// 終了時刻の選択肢はendTimeMin～24
const [endTimeMin, setEndTimeMin] = useState<number>(1)
const [endTimeOption, setEndTimeOption] = useState<{ value: number; label: string; }[]>([])
```

## 片方選択時にもう片方の選択肢の範囲を変更
絶対に範囲が被らないようにします。
```tsx
const handleStartChange = (value: number) => { setEndTimeMin(value + 1) };
const handleEndChange = (value: number) => { setStartTimeMax(value - 1) };
```

## 範囲の変更に伴い選択肢を自動作成
上で設定した値の変更があるたびにuseEffectで選択肢を生成しなおします。
```tsx
// 開始時間の選択肢
useEffect(() => {
    const options: { value: number; label: string }[] = [];
    for (let i = 0; i < startTimeMax + 1; i++) {
        options.push({ value: i, label: `${i}:00` });
    };
    setStartTimeOption(options);
}, [startTimeMax]);
```

```tsx
// 終了時間の選択肢
useEffect(() => {
    const options: { value: number; label: string }[] = [];
    for (let i = endTimeMin; i < 25; i++) {
        options.push({ value: i, label: `${i}:00`) });
    };
    setEndTimeOption(options);
}, [endTimeMin]);
```

## 最後に
初めてのReact、初めてのアプリ開発で手探りながらも自分の分かる要素を組み合わせてコードを書いてみました。
Formの中に入れ込む場合は提出後にstartTimeMaxとendTimeMinを初期値にリセットする処理を忘れずに。

もっと綺麗な解決法があるかもしれませんが、少しでも自分と同じ初心者エンジニアの方の助けになれば幸いです。
DockerでNext+TypeScriptの開発環境を作る方法

# はじめに
DockerでNext+TypeScriptの開発環境を作る方法はネットにあったのですが、自分の環境下ではうまくいかないこともあったのでメモとして共有させていただきます。
当方は「WSL2+Ubuntu-20.04」で開発を行っています。

# フォルダ構成
フォルダ構成は以下のとおりです。
project
 ├frontend
 │  └sample-app #空のフォルダ
 │  └Dockerfile
 └docker-compose.yml

# 具体的な手順
まず、Dockerfileを以下のとおり作成します。

```dockerfile
FROM node:18.16.0-alpine3.18
 
# ENV PROJECT /frontend
 
# WORKDIR ${PROJECT}

# RUN apk update && \
#     npm install -g create-react-app && \
#     npm install -g create-next-app

# COPY .${PROJECT} ${PROJECT}

# RUN npm cache verify
# RUN npm install


# CMD ["npm", "run", "dev"]
```
次に、docker-compose.ymlを以下のとおり作成します。

```docker
version: "3.3"

frontend:
    build:
      context: .
      dockerfile: "./frontend/Dockerfile.next"
    volumes:
      - ./frontend:/frontend
    ports:
      - "3000:3000"
```

以上のファイルを作成したらprojectディレクトリで以下のコマンドを実行しイメージを作成します。
```
docker compose build
```

イメージが作成出来たら、以下のコマンドを実行しコンテナに入りsample-appフォルダに移動します。

```
docker compose run --rm frontend sh
cd sample-app
```

そして、以下のコマンドを実行します。「sample-app」は任意の名前に変更可能です。
```
create-next-app sample-app --typescript
```
そうすると、以下のような質問が出てくるので答えていきます。
私は上から、「Yes,Yes,Yes,Yes,No」と答えました。

```
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use src/ directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias? … No / Yes
```

質問に答えると諸々の処理が行われます。Nextのプロジェクトの作成が完了したら以下のコマンドを実行してコンテナから抜けます。
```
exit
```

後は、作成されたNextプロジェクトのファイルフォルダ一式をfrontend直下に移動させます。そして、sample-appフォルダを削除します。最終的に以下のような構成になるはずです。
project
 ├frontend
 │  └app
 │  └node_modules
・　・　　
・　・　　
・　・　　
 │  └Dockerfile
 └docker-compose.yml

次に、Dockerfileのコメントアウトを解除します。

```dockerfile
FROM node:18.16.0-alpine3.18

# コメントアウトを解除

ENV PROJECT /frontend
 
WORKDIR ${PROJECT}

RUN apk update && \
    npm install -g create-react-app && \
    npm install -g create-next-app

COPY .${PROJECT} ${PROJECT}

RUN npm cache verify
RUN npm install


CMD ["npm", "run", "dev"]
```

解除したらprojectディレクトリで以下のコマンドを実行しイメージを再作成します。
```
docker compose build
```

その後、以下のコマンドを実行し、http://localhost:3000にアクセスしNextのアプリの画面が表示されれば開発環境の構築は完了です。
```
docker compose up
```

# まとめ
以上、とりあえず動作するDockerを用いたNext+TypeScriptの開発環境の作り方を説明しました。
システム開発・プログラミングに関わる原則の種類

プログラミングを含め、システム開発全般に関わる原則や法則、理論を纏めました。

# 目次

- [OAOO原則](#oaoo原則)
- [DRY原則](#dry原則)
- [驚き最小の原則](#驚き最小の原則)
- [ブルックスの法則](#ブルックスの法則)
- [デメテルの法則](#デメテルの法則)
- [ヴィルトの法則](#ヴィルトの法則)
- [コンウェイの法則](#コンウェイの法則)
- [逆コンウェイの法則](#逆コンウェイの法則)
- [割れ窓理論](#割れ窓理論)
- [ボーイスカウトルール](#ボーイスカウトルール)
- [YAGNIの法則](#yagniの法則)
***
# OAOO原則
「Once And Only Once」の略です。
プログラミングにて、同じ処理を行う際は似たソースコードを何度も書かずまとめなさいという考えです。

# DRY原則
「Don't Repeat Yourself」の略です。
同じ情報を複数の場所に重複して置かないようにするという考えです。
同じ情報が複数の場所にあると、修正が発生した際にその情報の数だけ修正が必要になり、
抜けや修正ミスが発生する可能性が高くなります。そのため、同じ情報は一箇所で管理すべきという原則です。
OAOO原則と似ていますがOAOO原則よりも含意が広く、DRY原則はシステム全体としての意味合いが強いです。なので、ドキュメントやDB設計にもDRY原則があてはめられます。
ソースコードの例でいうと、「そのコードが何をしているか」を記載しているコメントもDRY原則違反になります。ただ、コードからでは読み取れない意味のある補足情報はDRY原則違反にはならない。
※ソースコードとコメントで情報が異なるため。

:::note warn
「DRY原則を早まって適用しないこと」をGoogleが呼びかけていました。
共通化しすぎている箇所は分岐が多くなりがちで、逆に改修の難易度が上がる場合もありますね。
https://gigazine.net/news/20240605-google-not-dry-prematurely/
:::

# 驚き最小の原則
「利用者にとって、できる限り驚きの少ない設計を心がけましょう」という原則です。
たとえば、プログラムでも変数名がマジックナンバーになっていたり、
メソッドでメソッド名とは異なる処理を行っていたりすると驚きは強くなります。
プログラム以外にも当てはまりますが、
このように相手にとっての驚きを最小限に抑える選択をするべきという考えです。

# ブルックスの法則
遅れているプロジェクトに要員を追加すると、プロジェクトをさらに遅らせてしまうという法則です。
遅れてしまう理由としては、プロジェクトに慣れるまでの時間が必要なことや、
情報連携のために既存メンバーの工数も多くかかってしまうこと、などが挙げられます。

# デメテルの法則
最小知識の原則ともいわれます。
クラス間の結合度はなるべく減らした方が良いという原則です。
クラス間の結合度が高くなると、ユニットテストが難しくなったり (モックを多く作成しなくてはいけない等)、改修の際の影響範囲が広くなり、デグレが起きやすくなります。

# ヴィルトの法則
「ソフトウェアは、ハードウェアが高速化するより急速に低速化する」という法則です。
ハードウェアが進歩しても、ソフトウェアの速度は変わらないように感じるということです。

# コンウェイの法則
「システム設計は、組織構造をそっくり反映させたものになる」という法則です。
例えば、システム同士を結合する際、チーム同士で上手くコミュニケーションが取れていないと結合が難しくなります。
このように、コミュニケーションがうまくいっていない領域のシステムは問題点が多くなってしまいます。

# 逆コンウェイの法則
コンウェイの法則を元に考えられました。
コンウェイの法則に縛られてしまうのなら、
逆に実現したいシステムアーキテクチャーに合わせて組織体系をつくればよいという考えです。

# 割れ窓理論
割れている窓をずっと放置さていると、他の窓も割られやすくなるという理論です。
プログラムも、設計やコードの観点で悪い箇所が数箇所あり放置されていると、
改修を行う際も「悪いコードを書いてもいい、なぜならすでに汚いから」という考えになってしまい、その結果品質が下がりやすくなってしまいます。

# ボーイスカウトルール
コードを「来たときよりも綺麗にしよう」というルールです。
よく上げられる例として、「自分が来た時にキャンプ場が汚くなっていて、汚したのが自分ではなくても、キャンプ場を綺麗にしてからその場を去る」というものがあります。
それをプログラミングに当てはめた考え方です。
「コードをチェックアウトした際、一か所でよいからより美しくしてチェックインする」という考えが開発メンバーにあると、少なくとも品質が今より落ちることはありません。
新しいコードを書く場合も、もちろん美しく書きます。
たとえ少しずつでもモジュールを改善する努力を続けると、遠くない未来、今よりモジュールの品質が高まっています。

# YAGNIの法則
「You Aren't Going to Need it」の略です。
コードを書く際に、「これは後で必要になりそう」という部分は、今は書いてはいけない、という法則で、
「実際に必要となるまでは追加しない方がよい」という考え方です。
汎用性や拡張性を意識しすぎてしまうと、YAGNIの法則違反になってしまう可能性があります。
この法則が提唱されるのは、以下のような理由があります。
- 後で使うだろうと予測して書いても、結局その10％くらいしか後で使われない。そのため、費やした時間が無駄になる
- 必要以上の機能を追加すると、設計部分が複雑になってしまう (コードも無駄に複雑になってしまう可能性がある)
WindowsのSQLクライアントツール→LinuxのMySQLのリモート接続を確立する

## 経緯

- 学習用にOSなしの中古PCを購入してLinux(Ubuntu)をインストールした
- 何となくWindows端末→Linux端末にリモート接続できるようにした
- ある時、MySQLの環境構築を実施
- SQLで便利な機能がないかを発掘していたときがあった
- データベースやテーブルが徐々に増えたときに「そういえばクライアントツール（以下、**GUIツール**と記述）を使っていなかったな」とふと思う
- 「Windows端末のGUIツール→Linux端末のMySQLにリモート接続」って頑張ればできるんじゃない？と興味が湧いたので実現に向け行動を開始

## GUIツールの選定

### 外せない条件
無料で使用できること

### 候補

候補は以下の３つのどれか

- Beekeeper Studio
- A5:SQL Mk-2
- DBeaver

個人的には「Beekeeper Studio」「DBeaver」の二択

好みなのは「Beekeeper Studio」
使いやすそうなのは「DBeaver」
そんな印象

### ツール決定：DBeaver

決め手は２つ
- ER図が見れる
- 画面の雰囲気がどことなく「SQL Server」に似ていて親しみを覚えた

## 各種設定について

### 登場するもの

- PC1: Linux(Ubuntu)
  - リモート接続される側の端末
  - MySQL環境はこちらにある
  - バージョン: 22.04 LTS
- PC2: Windows
  - リモート接続する側の端末
  - GUIツールの「DBeaver」はこちらにインストールされている

### やりたいこと

「PC2:DBeaver→PC1:MySQL」のリモート接続を確立させて、DBeaverの画面上でDB操作を行える状態にする

### Linux端末の設定

するべきことはこちら
- IPアドレスを把握する
- MySQLのポート番号を把握する
- MySQLの設定ファイルを編集
- リモート接続用のMySQLユーザを追加

#### IPアドレスを把握する
DBeaverで接続設定するときに必要になる

`ip -4 a`
このコマンドを実行すれば確認できる

#### MySQLのポート番号を把握する

基本的には「3306」だと思うが例外もあり得るので調べ方を１つ記載

DB接続したあとに
`SHOW VARIABLES LIKE 'port'`
このコマンドを実行するとポート番号が可能

```sql
-- 実行例
mysql> SHOW VARIABLES LIKE 'port';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| port          | 3306  |
+---------------+-------+
1 row in set (0.01 sec)
```

#### MySQLの設定ファイルを編集

MySQL接続を許可するIPアドレスを管理している項目があるのでそれを編集する
※ちなみに筆者はここに辿り着くまでに結構遠回りしてしまった

対象ファイル: /etc/mysql/mysql.conf.d/mysqld.cnf
変更箇所: bind-address = xxx.xxx.xxx.xxx

初期設定では「bind-address = 127.0.0.1」となっていて、自端末からの接続のみ許可する状態

これを他のIPアドレスからの接続も許可するように変更する

```bash
# ファイル編集
sudo nano /etc/mysql/mysql.conf.d/mysqld.cnf
# 変更前
bind-address = 127.0.0.1
# 変更後
bind-address = 0.0.0.0
```

今回はIPアドレスを「0.0.0.0」に変えた
どこからの接続でも許可するという意味合い

IPアドレスの範囲を指定することもできるので使用用途に合わせて適宜設定値は変えるべき

#### リモート接続用のMySQLユーザを追加

DBeaverでMySQL接続するときに使うユーザを追加する必要がある

ユーザ追加権限のあるユーザ（rootとか）でMySQLに接続して
1. `CREATE USER '[user]'@'%' IDENTIFIED BY '[password]'`
2. `GRANT SELECT, INSERT, DELETE, UPDATE ON [databese].* TO '[user]'@'%';`

このコマンドを順番に実行する
リモート接続用のこのユーザには全権限は与えず最低限の権限を付与した

[user]: 任意のユーザ名
[password]: 任意のパスワード
[databese]: 接続対象のデータベース名

@以降の'%'は任意のIPアドレスを意味する
このユーザを利用すれば外部からのMySQLも可能となる

これでLinux端末側の設定は終わり


### Windows端末の設定

するべきことはこちら
- DBeaverの各種設定

こちらは接続する側なのでGUIツールの設定だけで良い

#### DBeaverの各種設定

1. DBeaverを起動
1. 画面上部の「データベース」を開く
1. 「新しい接続」を選択
1. 「MySQL」を選択して次へ
1. 接続設定画面
   Server Host: 「Linux端末の設定」で確認したIPアドレス
   Port: 「Linux端末の設定」で確認したポート番号
   Database: 接続対象のデータベース名
   ユーザ名: 「Linux端末の設定」で追加したユーザ
   パスワード: 「Linux端末の設定」で追加したユーザのパスワード
   その他: 初期値のままでOK
1. 入力が終わったら画面左下の「テスト接続」を押下
1. 接続成功すれば設定は完了

これで設定はおわり

## まとめ

「WindowsのSQLクライアントツール→LinuxのMySQLのリモート接続を確立する」という目的で環境設定を進めた。

リモート接続の設定が上手くいってDBeaverでテーブルやレコードが表示されたとき、
「おお！」と少しテンションが上がったのはここだけの話。

この経験を活かす機会はあまりなさそうだが、知ってて損はない知識だと思う。
Reactクラスコンポーネントのstaticについて


Reactでは、コンポーネントを作成するためにクラスベースのコンポーネントを利用することができます。

クラスコンポーネントには、特定の静的（static）メソッドやプロパティが存在します。今回は、それらの`static`についてわかりやすく解説します。

## staticとは？

まずは`static`自体について説明します。`static`はJavaScriptのキーワードの一つで、クラスに関連する静的なメソッドまたはプロパティを定義するために使います。これら静的なメソッドやプロパティは、クラスのインスタンスを生成せずとも、クラスそのものからアクセス可能です。

## Reactクラスコンポーネントでのstatic

Reactのクラスコンポーネントでは、`static`は特定の目的を果たすいくつかのメソッドとプロパティに使われます。以下にそれらを説明します。

### static defaultProps

`defaultProps`は、コンポーネントのデフォルトのpropsを定義するための静的プロパティです。これは、親コンポーネントからpropsが渡されなかった場合に使われます。

```javascript
class MyComponent extends React.Component {
  static defaultProps = {
    name: 'Default Name'
  };
  //...
}
```

### static propTypes

`propTypes`は、コンポーネントが受け取るpropsの型を指定するための静的プロパティです。これは開発中に型チェックを行い、意図しない型のpropsが渡された場合に警告を出すために使われます。

```javascript
import PropTypes from 'prop-types';

class MyComponent extends React.Component {
  static propTypes = {
    name: PropTypes.string
  };
  //...
}
```

### static contextType

`contextType`は、クラスコンポーネントでContextを利用するための静的プロパティです。このプロパティを設定すると、そのクラス内で`this.context`を通じて現在のcontext値にアクセスできます。

```javascript
import MyContext from './MyContext';

class MyComponent extends React.Component {
  static contextType = MyContext;
  //...
}
```

以上がReactのクラスコンポーネントで使われる主な`static`の用途です。
これらを理解することで、クラスコンポーネントの機能をより深く活用できるようになるでしょう。
Attrdictをimportする時に、 ImportError: cannot import name 'Mapping' from 'collections' 

## エラー
Attrdictをimportする時に、
ImportError: cannot import name 'Mapping' from 'collections' 
(/Users/***/anaconda3/lib/python3.10/collections/__init__.py)
Output is truncated. 
![スクリーンショット 2023-09-11 17.25.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233512/3e8e7f41-ddc5-1db3-dacb-47d7e193c54b.png)

## 解決方法：
矢印（---->）マークのあるエラー文からattrdictのファイルへアクセスして、
```
from collections import Mapping, MutableMapping, Sequence
```
importの部分の上記のcollectionsを下記のようにcollections.abcに書き換える。
```
from collections.abc import Mapping, MutableMapping, Sequence
```
【xarray】マスクを適用する (where)

この記事では、以下のライブラリを用いる。
```Python
import xarray as xr
import numpy as np
```

# マスクを適用する
`DataArray`のメソッド`where()`を利用する。

次の`DataArray`を例として説明する。
```Python
array = xr.DataArray([1, 2, 3], dims='x')
array
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/6b3573cd-b4b7-8c91-e76f-9aecc6cde1ac.png)

```Python
mask = xr.DataArray([True, False, True], dims='x')
mask
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/0aa7aa8c-548b-9f9a-db9e-3a10d2539994.png)

## 方法①
`where()`の引数に`mask`を指定する。`mask`が`False`の場所に`nan`が入る。
```Python
array.where(mask)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/d3ff6dbb-50fd-2a82-0c4d-c1c9dbe07cf2.png)


## 方法②
ビット反転演算子`~`を利用すると、`mask`が`True`の場所に`nan`が入る。

```Python
array.where(~mask)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/22025f5f-4d9c-d497-2097-e1d8749647f8.png)


# マスクを取得する
マスクを取得する方法については以下の記事を参照。

https://qiita.com/nonin/items/054e44e8dd8c2e508589

# 公式ドキュメント

https://docs.xarray.dev/en/latest/generated/xarray.DataArray.where.html

https://docs.xarray.dev/en/latest/user-guide/indexing.html#masking-with-where
Flutter iOSエラー（Failed to lookup symbol ）

# 現象
iOSのDebugモードビルドでは発生しないが、Releaseモードビルドでは下記エラーが発生した。
なおAndroidはDebug/Releaseともにエラーが発生しなかった。

Failed to lookup symbol 'HOGEHOGE': dlsym(RTLD_DEFAULT, HOGEHOGE): symbol not found

# 解決方法
筆者環境では下記で解決した。

https://github.com/fzyzcjy/flutter_rust_bridge/issues/250

![147508533-78f3d65d-ccf8-4da5-97bd-41c6c9327af8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/233237/dfbf87ce-fecb-5e29-5826-2583a5e5ec18.png)
Pythonでn秒遅らせて非同期で実行する


# したかったこと
n秒遅らせた非同期処理を書きたかった。


***
こんなコードがあったときに、move_file()をn秒遅らせて非同期で実行したかった。
```Python
def move_file(filename):
    # ファイル移動
    print(f"{filename} を移動しました")

filename = "example.txt"
move_file(filename)
print("その他の処理")
```

# 実装


```python
import threading
import time

def move_file(filename):
    # ファイル移動
    print(f"{filename} を移動しました")

def delayed_move_file(filename, seconds):
    print("遅延前")
    time.sleep(seconds)  # n秒遅延
    move_file(filename)

# スレッドを作成して遅延関数を起動
seconds = 3
filename = "example.txt"
thread = threading.Thread(target=delayed_move_file, args=(filename, seconds))
thread.start()
```

できた。

***

できたけど、元々のコードへの変更箇所が多すぎる。


# デコレータを用いた方法

デコレータの定義
```python
import threading
import time
from functools import wraps


def delay(seconds):
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            def delayed():
                time.sleep(seconds)
                func(*args, **kwargs)

            thread = threading.Thread(target=delayed)
            thread.start()

        return wrapper

    return decorator
```



```python
@delay(seconds=3) # 元のロジックにはこれをつけるだけ
def move_file(filename):
    # ここでファイル移動のロジックを書く
    print(f"{filename} を移動しました")

filename = "example.txt"
move_file(filename)
print("その他の処理")
```

元のロジック部分をいじらず、遅延非同期実行に成功。
【xarray】マスクを取得する (notnull, isnull)

この記事では、以下のライブラリを用いる。
```Python
import xarray as xr
import numpy as np
```

# マスクを取得する
`DataArray`のメソッド`notnull()`または`isnull()`を使うと、マスクを取得することができる。

:::note info
**基本的には`notnull()`を用いてマスクを取得するとよい。**
:::


次の`DataArray`を例として説明する。
```Python
array = xr.DataArray([1, np.nan, 3], dims='x')
array
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/f104659f-db4a-daa2-37a3-70bff49c463e.png)


## notnull()
`notnull()`を使うと、`nan`の場所に`False`、それ以外の場所に`True`が入った`DataArray`を取得できる。

```Python
array.notnull()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/b5787b5e-6997-6bf2-d609-566008673668.png)

## isnull()
`isnull()`を使うと、`nan`の場所に`True`、それ以外の場所に`False`が入った`DataArray`を取得できる。

```Python
array.isnull()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3552468/40b7b9e2-3fc3-e52d-c731-bc7015e81e9c.png)

## DataSet.notnull() / DataSet.isnull()
`DataSet`にも同様のメソッドが用意されている。

# マスクを適用する
マスクを適用する方法については以下の記事を参照。

https://qiita.com/nonin/items/80734f1de376f61fe380

# 公式ドキュメント

https://docs.xarray.dev/en/latest/generated/xarray.DataArray.isnull.html

https://docs.xarray.dev/en/latest/generated/xarray.DataArray.notnull.html

https://docs.xarray.dev/en/latest/generated/xarray.Dataset.isnull.html

https://docs.xarray.dev/en/latest/generated/xarray.Dataset.notnull.html
登記所備付地図XMLデータの変換ツールを比較

# はじめに

G空間情報センターにて公開されている登記所備付地図 (https://front.geospatial.jp/moj-chizu-xml-readme/) は、法務省が公開しているものはXMLデータとなっているため、そのままではGISソフトなどで表示することが出来ません。

ただし、任意座標系のデータを除いた公共座標系（平面直角座標系）で記述されたデータは、G空間情報センターによってシェープファイル（Shapefile）やGeoJSON形式に変換されて公開されており、ダウンロードしてそのまま使うことが出来ます。

ここでは XMLデータを GISソフトなどで扱うことが出来るフォーマットに変化するツールについて比較してみます。

# 地図XMLフォーマットについて

XMLデータのフォーマットの詳細は法務省のサイトで公開されています。

[地図情報システムで取り扱う地図情報のデータ形式について](https://www.moj.go.jp/MINJI/minji05_00171.html)

変換ツールでは、形状を表す空間属性と共に、様々な値を含む主題属性も出力されています。

# 変換ツールの紹介

代表的な変換ツールをいくつか紹介します。

## デジタル庁コンバーター

元々農林水産庁の方が開発されたコンバーターが[デジタル庁](https://www.digital.go.jp/news/4b7250a3-3fcf-4b83-8d52-4bb131e1ba9d/)から公開されています。

- Pythonで記述されている
- コマンドラインから実行される
- XMLを GeoJSONに変換し、出力ファイルを自動生成する
- ソースコードは GitHubで公開

https://github.com/digital-go-jp/mojxml2geojson

## MIERUNE社 QGISプラグイン

[MIERUNE社](https://www.mierune.co.jp/)が公開している [QGIS](https://qgis.org/)のプラグインの以下のような特長があります。

- Pythonで記述されている
- QGISアプリケーション内でプラグインとして利用する
- ZIPファイルのまま読み込める
- QGIS内でレイヤーを生成する
- 出力は QGIS内でフォーマットなどをユーザーが設定する
- ソースコードは GitHub で公開

https://github.com/MIERUNE/qgis-mojxml-plugin

## SIMA・地籍フォーマット2000・法務省地図XML⇒GIS

- Windowsの Excelで動作する VBAマクロです
- XMLをシェープファイル(Shapefile)形式に変換できます
    - ※GeoJSONは途中で止まってしまったため未確認

https://www.vector.co.jp/soft/dl/winnt/business/se523305.html

# 変換されたデータ比較

変換後のデータに含まれている主題属性は、以下のようにツールによって多少違いがありました。

- fid は QGISで地物に付与される IDです。
- 代表点経度・緯度はデジタル庁コンバータが独自に付与している値です。
- SIMAではシェープファイルに出力したため、属性名の文字数制限で属性名が違っているようです。

| 主題属性 | デジ庁 | MIERUNE | SIMA | 備考 |
|:-:|:-:|:-:|:-:|:-:|
| 筆ID | ○ | ○ |   |   |
| ID |   |   | ○ |   |
| version | ○ |  | ○ |   |
| 座標系 | ○ | ○ | ○ | 公共座標n系、任意座標系 |
| 座標値種別 | ○ | ○ | ○ | 測量成果、図上測量 |
| 測地系判別  | ○ | ○ |  | 測量、変換 |
| 測地判別  |  |  | ○ | 測量、変換 |
| 精度区分 | ○ | ○ | ○ | 甲三、乙一、など |
| 地図名  | ○ | ○ | ○ |  |
| 地図番号  | ○ | ○ |  |  |
| 縮尺分母  | ○ |  |  |  |
| 市区町村コード | ○ | ○ |  |  |
| 市区町村C |  |  | ○ | ※シェープファイルの文字数制限 |
| 市区町村名  | ○ | ○ | ○ |  |
| 大字コード | ○ | ○ | ○ |  |
| 丁目コード | ○ | ○ | ○ |  |
| 小字コード | ○ | ○ | ○ |  |
| 予備コード | ○ | ○ | ○ |  |
| 大字名 | ○ | ○ | ○ |  |
| 丁目名 | ○ | ○ | ○ |  |
| 小字名 | ○ | ○ | ○ |  |
| 予備名 | ○ | ○ | ○ |  |
| 地番 | ○ | ○ | ○ |  |
| 筆界未定構成筆 | ○ | ○ |  |  |
| 代表点緯度 | ○ |  |  | デジ庁コンバーター独自 |
| 代表点経度 | ○ |  |  | デジ庁コンバーター独自 |
| fid |  | ○ |   | ※QGIS独自 |

読み込み変換時の座標参照系やライセンスに関しては、以下のような違いがありました。

| ツール | 変換データの測地系 | ライセンス表記 |
|:-:|:-:|:-:|
| デジ庁  | JGD2011  | MIT License |
| MIERUNE  | WGS84 | GPL 2.0  |
| SIMA  | JGD2000 ? | GPL |

# XMLデータのダウンロード

XMLデータはG空間情報センターからダウンロード可能です。

https://front.geospatial.jp/moj-chizu-xml-readme/

# おわりに

2023年8月には、2023年1〜2月分のデータが追加公開されました。今後は年１回程度の更新が予定されていますので、より変換作業が簡単になるようなツールが揃っていくと良いですね :-)


# 参考リンク

https://qiita.com/mkyutani/items/5e932625982f1c4beaf3

https://qiita.com/T-ubu/items/3e794ce899ded584c6aa
Databricksの新たなPricingシステムテーブルを試してみる

こちらのアップデートです。SKUごとの単価がわかるようになりました。

**Pricing system table is now available (Public Preview)**

https://docs.databricks.com/en/release-notes/product/2023/september.html#pricing-system-table-is-now-available-public-preview

> [システムテーブル](https://docs.databricks.com/ja/administration-guide/system-tables/index.html)に、SKUのコストの時間変化を監視できるプライシングテーブル (`system.billing.list_prices`)が追加されました。[Pricing system table reference](https://docs.databricks.com/en/administration-guide/system-tables/pricing.html)をご覧ください。

# システムテーブルの有効化

```sh
curl -v -X PUT -u <DatabricksアカウントオーナーID>:<パスワード> "https://<ワークスペースURL>/api/2.0/unity-catalog/metastores/<メタストアID>/systemschemas/billing" | jq
```

:::note
**注意**
過去にbillingを有効化している場合、`system.billing.list_prices`にアクセスしても権限不足のメッセージが表示される場合があります。その場合には、一度billingを無効化し、再度有効化してください。

```sh
curl -v -X DELETE -u <DatabricksアカウントオーナーID>:<パスワード> "https://<ワークスペースURL>/api/2.0/unity-catalog/metastores/<メタストアID>/systemschemas/billing" | jq
```
:::

# Pricingシステムテーブルへのアクセス

カタログエクスプローラ`system.billing.list_prices`が表示されます。
![Screenshot 2023-09-11 at 16.29.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/069660c0-9511-b850-bb59-da41a6e8dd2e.png)

`pricing`列に金額が表示されます。
![Screenshot 2023-09-11 at 16.30.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/eee3ec5d-1330-9b26-a31a-ff1b23124ab6.png)

# テーブルのスキーマ

https://docs.databricks.com/en/administration-guide/system-tables/pricing.html#pricing-table-schema

| カラム名 | データ型 | 説明 | 例 |
|:--|:--|:--|:--|
| `price_start_time`  |timestamp   | この金額が有効になった時刻  | `2023-01-01T09:59:59.999Z`  |
| `price_end_time`  | timestamp  | この金額が有効で無くなった時刻  |  `2023-01-01T09:59:59.999Z` |
| `account_id`  | string  |  このレポートが作成されたアカウントID | `1234567890123456`  |
| `sku_name`  | string  | SKU名  | `STANDARD_ALL_PURPOSE_COMPUTE`  |
| `cloud`  |  string |  この価格が適用されるクラウド名。適用可能な値は`AWS`、`AZURE`、`GCP`です。 |  `AWS` |
| `currency_code`  |  string | 価格の単位  | `USD`  |
| `usage_unit`  | string  | 課金される単位  |  `DBU` |
| `pricing`  |  struct |  リストプライスのレートが公開された際の価格情報を含む構造化されたデータフィールド。キー`default`は、シンプルな見積もりに利用できる単一の値を常に返却します。いくつかのプライシングモデルでは、より詳細な情報を提供する追加のキーが含まれることがあります。 | {default: $0.10}  |

# サンプルクエリー

## 特定の日における特定のSKUのリストプライスの取得

```sql
SELECT sku_name, price_start_time, pricing.default
FROM system.billing.list_prices
WHERE sku_name = 'STANDARD_ALL_PURPOSE_COMPUTE'
AND price_start_time <= "2023-01-01"
ORDER BY price_start_time DESC
LIMIT 1
```

2013/1/1に制定されたALL PURPOSEコンピュートのリストプライスは1DBUあたり0.4ドルとなります。
![Screenshot 2023-09-11 at 16.47.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/ab420a95-f785-e469-f2ab-13d57017d584.png)

こちらで確認できます。




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

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


### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Xserverドメインで独自ドメインを取得してWraptasに設定するまで

## やりたいこと

独自ドメインを取得して、Wraptasに設定したい。
知識がなさすぎて小一時間悩んだので記録に残します。

## 独自ドメイン取得後の設定方法

#### 1. ネームサーバー設定を変更する

「Xserver Domain」を選択

初期ではこれが「Xserver Domain」になっておらず、後述のDNSレコード設定をしようとしてもできませんとハネられてハマってしまった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/a11889ea-4687-5a50-d3b7-a3e2b1f4b175.png)


#### 2. DNSレコード設定を追加する

これでDNSレコードを追加できるようになるので、以下3点をWraptasの指定通りに記載して追加。

- ホスト名（空白でOK）
- 種別
- 内容

[👉　記載内容は公式を参照](https://wraptas.com/4d19a3867e83402f9c7d2310ebe4b729)

記載例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/62aee053-22f2-713f-cc7b-c65036e90f4f.png)

#### 3. Wraptasの管理画面から独自ドメインを設定

※「解除」となっているあたりに「独自ドメイン設定」ボタンがあります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/be05349f-f428-664b-bce3-c9238148c75c.png)


#### 4. 反映を確認

1分程度で割とすぐに反映されていた
reference brokenエラーでGit fetchできない

## 事象

Sourcetreeで作業中にPCが落ちてしまった

まずSourcetreeがエラーで立ち上がらないので、 再インストールから始める。 
インストールが終わって、フェッチしようとすると下記エラー

:::note alert
git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks -c credential.helper= -c credential.helper="C:/Users/hogeuser/AppData/Local/ATLASS~1/SOURCE~1/GIT_EX~1/GIT-CR~1.EXE" fetch origin
error: cannot lock ref 'refs/remotes/origin/master': unable to resolve reference 'refs/remotes/origin/master': reference broken
From https://github.com/*****/*****
! [new branch]      master     -> origin/master  (unable to update local ref)
// エラー終了しました。エラーの内容は上記をご覧ください。
:::

## 解決方法

＞`'refs/remotes/origin/master': reference broken` 壊れてるらしいので
名前を変えてもう一度フェッチしたら自動で新しいmasterを作ってくれました
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/243523/75f81bb8-8259-1fae-3f01-885f588c76d6.png)
PCが落ちたときに終了処理が間に合わずファイルも壊れちゃったみたいです
Laravel で json をDBに保存した時にUnicodeエスケープされる

## Eloquent での json の使い方
(環境: PHP 8.1以上、Laravel 10)
LaravelのEloquent(Model) で json を扱う時は、モデルに以下のように記述と思います。
![casts](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/8e7828ee-6e01-4391-eedf-9a4362a651fa.png)

入出力する際に json を encode/decode することなく扱えます。
![配列をそのまま保存](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/c9d3de8c-341f-9d73-b74e-5c9ce91de48d.png)
casts 便利ですね。

## 罠
非常に便利ですが、罠があります。
環境によって unicode にエスケープされたりされなかったりするのです。
![unicodeエスケープされたデータ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71497/43dc2f59-024e-40ec-18ba-549ce3d26c8d.png)

## どういう時困るか
実はPHPで通常利用する上では特に困りません。
しかしDB検索時の条件に指定する時などに困ります。

たとえば files テーブルの tags というカラムに配列でタグを入れていくという仕様になっていたとします。
そしてそのタグを条件に検索したい時、以下のようなSQLを発行すると思います。
`select * files where tags LIKE "%景色%";`

ところが、DB上では `\u666f\u8272` というようにユニコードエスケープされた状態で保存されているので、文字列が不一致として認識されます。
これだとタグ検索ができません。

### 解法1: 検索する時にUnicodeエスケープする
シンプルです。
しかし環境によってエスケープされないこともあるので、両方に対応するコードを記述する必要があります。

```php
File::where(function ($query) {
    $query->where('tags', 'LIKE', '%' . $escaped . '%')
        ->orWhere('tags', 'LIKE', '%' . $unescaped . '%');
});
```

環境によって不要なコードが含まれているので冗長ですし、DBに無駄な負荷がかかります。
また php は標準で ユニコードにエスケープする関数がないので、自前で用意しなければなりません。

### 解法2: json_encode 時にエスケープしない
Eloquent で json を cast しているのは `Illuminate\Database\Eloquent\Casts\Json` というクラスです。
この中で通常は `json_encode` が呼び出されています。

```php
public static function encode(mixed $value): mixed
{
    return isset(static::$encoder) ? (static::$encoder)($value) : json_encode($value);
}
```

コードをよく見ると `static::$encoder` があれば、それを用いてエンコード処理してくれるので、どうやらここを使えばうまくいけそうです。

さて `json_encode` は第2引数でフラグを設定することができます。
そして `JSON_UNESCAPED_UNICODE` という、名前の通りユニコードのエスケープをさせないためのフラグが定義されています。

これらを用い `App\Providers\AppServiceProvider` の `boot` 関数内で以下のように記述してあげます。
```php
public function boot(): void
{
    Json::encodeUsing(fn ($value) => json_encode($value, JSON_UNESCAPED_UNICODE));
}
```
これで DB に保存する時にマルチバイトがユニコードエスケープされないようになります。

## 注記
* その他にも casts を使わずに自分で encode/decode する方法もあり
* そもそも json を検索しない工夫をする (アプリケーションの規模やコストに合わせ)
* `fn () => ...` は [アロー関数](https://www.php.net/manual/ja/functions.arrow.php)
* LIKE 検索するときはきちんとSQLインジェクション対策をしましょう
* JSON の[定義済み定数](https://www.php.net/manual/ja/json.constants.php)
アンリアルエンジン　ブループリント解説

# 概要

本記事では、開発初心者を対象にアンリアルエンジンで使われるブループリントについてまとめます。

# C++言語とコンパイル

Unreal Engineは、ソースコードはC++というオブジェクト指向の言語となります。

通常、エンジンやプロジェクトのソースコードを更新した際は、Vidual StudioやRider、Note++等の統合開発環境（IDE）を使って、プログラムに使う言語（Human  readable）からコンピュータが読むためのBinaryファイルにします。
この作業を、**コンパイル**と呼びます。

※Live++もしくは、UnrealSyncを使えば、コンパイルの手間を省くことができます。


# ブループリント

開発者がゲームのファンクションなどを追加する際、C++言語もしくうは**Blueprint**というビジュアルコーディングという機能を使って、ゲームプロジェクトに簡単にプログラムを加えることができます。

# クラス

ブループリントを作成する際、元となる親クラスを指定します。
|クラスの種類|説明|
|----|----|
|Actor|ワールドに配置またはスポーンすることができるオブジェクト|
|Pawn|「所有可能」であり、コントローラから入力値を受け取るアクタ|
|Character|歩行、走る、ジャンプなどの能力を含んだポーンの一種|
|PlayerController|プレイヤーが利用するポーンの制御を行うアクタ|
|Game Mode|プレイ中のゲーム、ゲームのルール、スコア採点方法やゲームの様々なな側面を定義|

# インスタンス

コンテントブラウザーに作成したブループリントクラスは、同じレベルでインスタンスとして使用することができ、ブループリントの変更が反映されることになる。

# データアトリビュート
エンジンに保存されたデータを効率よくRAM等に渡すため事前に決めておくデータ

変数(Variable)は、 変数名とデータタイプの指定が必要。


# イベントグラフ
Begin play: ゲーム開始次第、イベントが開始される
Overwrap
Event tick: 毎フレーム、イベントが実行される


# コンストラクションスクリプト
コンポネントのプロパティをカスタマイズできる
パブリック変数にすることで、各インスタンスのプロパティを個別に変更できる

#
LinuxからMac移行時のヒント

Linuxに似ているようでですが、移行時に戸惑うことも多い癖のあるMacを使えるようになるまでのヒント集

## Homebrewをインストール


Homebrewをイントールしたら下記フォルダ下にファイルやフォルダが作成されている
`/opt/homebrew/`
`/usr/local/`


## oh-my-zshをインストール

## MacでプリンターのIPアドレスを見つける
CUPS

```shell:
cupsctl WebInterface=yes
open http://localhost:631/printers
```


## MacでJekyll
Macには、すでに古いバージョンのRubyがデフォルトでインストールされている。
Jekyllには、新しいバージョンをインストールするが、
バージョン間でスイッチできるようにchrubyをインストールする。
```shell:
brew install chruby ruby-install
```
以下、二つの方法がある

1.　パスを設定して、chrubyが新しいRubyを使えるようにする。
```shell:
echo "source $(brew --prefix)/opt/chruby/share/chruby/chruby.sh" >> ~/.zshrc
echo "source $(brew --prefix)/opt/chruby/share/chruby/auto.sh" >> ~/.zshrc
echo "chruby ruby-3.2.2" >> ~/.zshrc
```

2.　Ruby3.1.x以上を使うならOpenSSL3をインストール
```
brew install openssl@3
```

そして、Rubyをインストール
```
ruby-install 3.2.2 -- --with-openssl-dir=$(brew --prefix openssl@3)
```

一度、ターミナルを閉じて、新しいセッションでchrubyのコマンドでバージョンを指定
```
chruby 3.2.2
```


Reference:
[The fastest and easiest way to install Ruby on a Mac in 2023 ](https://www.moncefbelyamani.com/how-to-install-xcode-homebrew-git-rvm-ruby-on-mac/#configure-your-shell)