OmniAICreator/Qiita-1.07M huggingface dataset:
APIに対してPOSTした際の備忘録

ES6（というかReact）とjQueryがデバイスで使い分けされている（PCとSPで使っているjsが違う、みたいな感じ）、変則的な環境で同一の挙動（APIに必要なデータをPOSTする）をさせる必要が出たことがあり、当然ながらそれぞれ記述がちょっと異なる形になったので、その備忘録です。
（似たような件で別の記述することがあったら随時増やそうと思います）

また、大体POSTする際はデータをjson化することが多いと思うのですが、今回の件は逆にjson化してはならず、けれどもES6ではjQueryのように連想配列状態でbodyにセットしても400エラーが出てしまったので、ならどうするかと頭を抱えた末のことだったのも、記録として残す発端だったりします（調べても、大体のところがデータをjson化させてる記述ばかりだったので…）。
あんまりなさそうなケースですが、似たようなことで頭を抱える人の助けになることがあったらこれ幸い。
後はちょっとjQuery⇔ES6で変換して記述してみたい人の参考になったりとか…するんですかね、これ。

もっと良い書き方、やり方があったら教えていただけると大変助かります。

# ①ES6での記述
送りたいデータを配列ではなく「URLSearchParams」や「FormData」といったオブジェクトにして送る必要がありました。
ちなみにこれをやる時はContent-Typeを指定してしまうと、ちゃんと送られない模様。
```javascript:ES6
let _endPoint = 'APIのURL';

let _postdata = new URLSearchParams();
_postdata.append('keyA', 'valueA');
if (条件分岐){
    _postdata.append('keyB', 'valueB-1');
} else {
    _postdata.append('keyB', 'valueB-2');
}

let _options = {
	method : 'POST',
	mode : 'cors',
	credentials: 'include',
	headers : {
		'pragma' : 'no-cache', 
		'cache-control' : 'no-cache', 
		'X-Requested-With' : 'XMLHttpRequest'
    },
    body : _postdata
};

fetch(_endPoint, _options)
	.then(_res => {
		if (_res.status===200){
			return _res;
		} else {
			throw Error(_res.status);
		}
	})
	.then(
		(_result) => {
			console.log('success');
		},
		(_error) => {
			console.log(_error);
		}
	)
```

# ②jQueryでの記述
json化がいらない（してはいけない）ケースなのですが、dataTypeは「json」を指定する必要がありました。
```javascript:jQuery
var _postAjax = function(_data) {
	"use strict";
	return $.ajax({
		url: 'APIのURL',
		dataType: 'json',
		type: 'POST',
		data: _data,
		crossDomain: true,
		cache: false,
		async: false,
		headers: {
			'X-Requested-With': 'XMLHttpRequest'
		},
		complete: function(xhr, txtStatus){
			switch(xhr.status){
				case 200 :
					console.log('success');
					break;
				default :
					console.log('error: ' + xhr.status);
					break;
			}
		}
	});
}

var _postData = {
	keyA : valueA,
	keyB : null
};

if (条件分岐){
	_postData.keyB = 'valueB-1';
} else {
	_postData.keyB = 'valueB-2';
}

_postAjax(_postData);
```
DjangoアプリとAzureWebApps　静的ファイルが読み込めない。

AzureWebAppsへのデプロイ時にCSSなどの静的ファイルの読み込みに苦労した為、備忘録として残します。
初投稿ですので読みづらい点はご容赦下さい。

# Whitenoiseを使って解決！
whitenoiseとは何？？
「Python Web アプリ向けの大幅に簡素化された静的ファイル サービス」だそう。
詳細は[こちらのドキュメントから](https://whitenoise.evans.io/en/stable/ "whitenoise")
ふむふむ。こんなものがあったのか…

まずはWhitenoiseのインストール
```
pip install whitenoise
```

settings.pyに以下を追記
```
INSTALLED_APPS = [
...
    'whitenoise.runserver_nostatic',
...
]
```
```
MIDDLEWARE_CLASSES = (
    'whitenoise.middleware.WhiteNoiseMiddleware',
...
```
STATIC_URLやSTATIC_ROOT_ROOTあたりに以下追記
```
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
```

`requirements.txt`にも`whitenoise`追加忘れずに！

さて、deploy！
manage.py collecstaticは自動でやってくれるっぽい。
動いた！ちゃんと反映されてる！！

さんざんstatic関連の設定してもcss読み込めず苦労してましたが、あっさり解決しました。
検索力の無さを痛感しました…精進します！
USDA(Ascii) と USDC(Crate binary) の違いのメモ

ASCII 表現と Binary 表現, だいたい似ているけど細かいところで違いがあります.

## Stage(layer) meta

USDA は `documentation` は `doc` として処理される.
USDC では `documentation`

`documentation` が本来の名前であるが, ASCII では省略形 `doc` を使っている.
 
## USDC(Crate)だけにあるもの

* `primChildren`(`token[]`) : Metadata としてのみ存在するっぽい


`tokens[0]` は `;-)` のときがある

https://github.com/PixarAnimationStudios/USD/blob/3abc46452b1271df7650e9948fef9f0ce602e3b2/pxr/usd/usd/crateFile.cpp#L2471


### Inlined ValueRep の精度削減

データ圧縮のためか, たとえば xformOp の scale など float3 型のところが half3 型で保存されていたりする.
(`typeName` が `float3` で, `default` の型が `half3` など)


## Quaternion

Ascii では `(angle, x, y, z)` (e.g. `[1, 0, 0, 0]`) であるが, 

https://github.com/PixarAnimationStudios/USD/blob/3abc46452b1271df7650e9948fef9f0ce602e3b2/pxr/base/gf/quatf.h#L287

binary(`GfQuat` 型のメモリレイアウト)では `(x, y, z, angle)` となる.

https://github.com/PixarAnimationStudios/USD/blob/3abc46452b1271df7650e9948fef9f0ce602e3b2/pxr/base/gf/quatf.h#L257
CD-ROM .iso ファイルの EDC/ECC の復元

いまさらですが、CD-ROM の .ISO ファイルにパッチ入れたときに、エラー訂正はどうすればいいのか?

# 手順

1. ないものは作る

# ないものは作る

## 2000年(古すぎ)問題

CD-ROM なんて何をいまさら感ですが、頼みの GeoCities なども閉鎖していますので、ユーザー情報がない。
仕方なし、オレンジブックを見ながら書きますか！

## EDC

EDC は テーブル指定の CRC32 なのでテキトーに書く

## ECC

EDC が合ってれば使わないとは思いますが、XOR の塊を処理

## MODE1

通常の CD-ROM はこれ。

## MODE2 Form1

PlayStation とかはこれ(XAだしねー)

- MODE1 にサブヘッダがついたもの
  - EDC/ECC は範囲が異なるが計算は一緒
  - ヘッダを ZeroFill するのがポイント(ハマりポイント)

## MODE2 Form2

- EDC のみ
  - ECC 分はまるまるデータに

## 結果

C++ でテキトーに作成しました。
https://gitlab.com/nekodevteam/nyaiso

# 最後に

古いゲーム データをいじる人とかは困ると思うんで書き遺しておきました。
CD-ROM のゲームを色々復刻してください。。。
超初歩: Zig から C の関数を呼び出してみた

ZigはC/C++の捻れた仕様を取り除いて現代的にしたような言語です。「GoのGoroutine抜き」みたいな感じです。

Zigの特徴的なところに、`zig`コマンドにビルドツールが内蔵されており、CやC++のコードも一緒にビルドできることがあります。

それでは、C言語の関数をビルドして呼び出してみましょう。

# ソースコード

https://github.com/doloopwhile/calling-c-func-from-zig-example

```zig
// src/main.zig

const std = @import("std");
const foo = @cImport({
    @cInclude("foo.h");
});

pub fn main() anyerror!void {
    std.log.info("All your codebase are belong to us.", .{});
    std.log.info("foo = {d}", .{foo.fooFunc()});
}

test "basic test" {
    try std.testing.expectEqual(10, 3 + 7);
}
```


```zig
// src/foo.h

int fooFunc();
```


```zig
// src/foo.c

int fooFunc() {
  return 42;
}
```


```zig
// build.zig

const std = @import("std");

pub fn build(b: *std.build.Builder) void {
    const target = b.standardTargetOptions(.{});
    const mode = b.standardReleaseOptions();
    const exe = b.addExecutable("build-zig", "src/main.zig");
    exe.addIncludeDir("src");
    exe.addCSourceFiles(&.{"src/foo.c" },
     &.{
        "-std=c99",
        "-Wall",
        "-DLUA_ANSI",
        "-DENABLE_CJSON_GLOBAL",
        "-DLUA_USE_MKSTEMP",
    });
    exe.setTarget(target);
    exe.setBuildMode(mode);
    exe.install();

    const run_cmd = exe.run();
    run_cmd.step.dependOn(b.getInstallStep());
    if (b.args) |args| {
        run_cmd.addArgs(args);
    }

    const run_step = b.step("run", "Run the app");
    run_step.dependOn(&run_cmd.step);
}
```

# 実行例

```
$ zig build run
info: All your codebase are belong to us.
info: foo = 42
```

やったね！
enumを利用してcheck_boxを作成し絞り込み検索を行う

## やりたいこと
railsでタスク管理アプリを作成。
enumで定義したタスクの状態を検索フォームにcheck_boxとして作成し、
絞り込み検索を行いたい。
※以下のようなイメージ
![enum check_box.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/857784/f96d2779-5701-a6c5-814e-29e8092aa2f6.png)
## 実装したこと

- **controller**
```rb
class TasksController < ApplicationController
  def index
    @tasks = current_user.tasks.
               status(params[:status])
    @status = params[:status]
  end
end
```
実際には他にも絞り込みたい条件はあると思いますが、
今回はstatusのみに絞ってます。

- **view**
```erb
 <div class="form-group col-5">
      <%= f.label :status, Task.human_attribute_name(:status) %>
      <div class="radio">
        <%= f.collection_check_boxes :status, Task.statuses, :first, :first do |s| %>
          <%= s.check_box checked: @status.nil? || @status.include?(s.value) %>
          <%= s.label { Task.human_attribute_name("status.#{s.text}")} %>
        <% end %>
      </div>
    </div>
```
enumを利用したイメージ画像のようなcheck_boxはこれで作れると思います。

- **model**
```rb
class Task < ApplicationRecord
  enum status: { waiting: 0, working: 1, completed: 2 }
  
  scope :status, ->(s) { where(status: Task.statuses.keys & s) if s.present? }
end
```
modelにscopeを定義しました。
scopeについてはRailsガイドをご参照ください。

https://railsguides.jp/active_record_querying.html#%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%97

スコープの中身について説明します。
- scopeで `->(s)` のように書けばcheck_boxで選択されたパラメータを引数として渡すことができます。
- `Task.statuses.keys`は`enum`のkey部分の配列です。

```rb
irb(main):001:0> Task.statuses
=> {"waiting"=>0, "working"=>1, "completed"=>2}
irb(main):002:0> Task.statuses.keys
=> ["waiting", "working", "completed"]
```
- `Array#&`は集合の積演算です。 
check_boxで `着手中(working)`と`完了(completed)`で検索した場合、
以下のような処理になるイメージです。
```rb
## Task.statuses.keys & ["working", "completed"]
irb(main):001:0> ["waiting", "working", "completed"] & ["working", "completed"]
=> ["working", "completed"]
```

これでTaskモデルに対して
`SELECT "tasks".* FROM "tasks" WHERE "tasks"."user_id" = 1 AND "tasks"."status" IN (1, 2)`のようなクエリを渡すことができました。

以上、enumを利用したcheck_boxを作成し絞り込み検索を行う実装でした。
少しでも参考になれば嬉しいです。
Photon Fusion for Unityのシーン読み込み管理の基礎

# はじめに

ミニゲームやミニマムなチームでの開発であれば、シングルシーンでもゲームを完成させる事ができるでしょう。しかしゲームやチームの規模が大きくなるにつれ、読み込み負荷の増加や作業の分担の観点から避けて通れなくなってくるのが、マルチシーン開発です。
編集については影響ありませんが、実行してPhotonに接続した時にはオンラインマルチゲーム特有の同期や読み込みの問題が出てきます。
本記事ではPhoton Fusionにおけるマルチシーン開発時の基本について、公式のサンプルプロジェクトを元に紹介します。

### 前提記事

Photon Fusionの基本的な解説は別記事で行っています。詳しく知りたい方は以下のリンクからご参照下さい。

[Photon Fusion for Unityの導入手順とPUN2との機能比較](https://qiita.com/nimushiki/items/d6fe4f0cbe0437677fa8)

### 動作確認環境

Windows 10 Home 21H2
Unity 2020.3.27f1
Fusion SDK 1.1.1 F Build 512

# Photon Fusionにおけるマルチシーン開発

## マルチシーンとは

Unity5.3から追加された機能で、複数のシーンを読み込み・編集する機能です。主にUIやフィールドを分割し、読み込み負荷の軽減や作業分担のために活用されます。

## 必須要素

マルチシーンのPhoton Fusion対応に最低限必要といえる要素は一つだけで、それはホスト・サーバーが事前に必要なシーンをキャッシュしておくことです。
あとは必要な時にSceneManager.LoadSceneAsyncなどを実行すればロードすることができます。
しかしロードやアンロードを任意のタイミングで問題なく行うには、様々な実装が必要になります。各マシンでの状態の差異によってゲームの進行に問題が出ないように、シーンの必要性や更新のチェックをする、読み込みの許可拒否、クライアント・ホストで動作を切り分ける、などです。
公式が公開しているサンプルでは、こういった基本となる実装がなされているので紹介します。

# サンプルについて

公式のサンプルプロジェクトは以下のページからダウンロードすることができます。

[Fusion シーンの読み込み | Photon Engine ダウンロード](https://doc.photonengine.com/ja-jp/fusion/current/samples/technical-samples/fusion-scene-loading#_jb0qd6m1ewila7l)

使用されているSDKのバージョンは1.1.1ですが、最新版（1.1.2、2022/09/01現在）にアップデートしても問題ありません。
ただし、現行のサンプル（ver1.1.1）はマルチピアモードと共有モード接続に対応していない点には注意が必要です。

## サンプルの使い方

サンプルを動かすには以下の手順が必要です。

- 公式サイトのダッシュボードでAppIDを作成してコピーする
- Fusion>Fusion Hub>Fusion Setup>FusionAppIDにAppIDをペーストし認証する
- Project>Scenes>Mainのシーンを読み込み再生する
- Buttons Sample/Character Sampleボタンを押すと、それぞれのデモシーンが呼ばれる
    - Photonに接続するのはシーンが呼ばれた後
    - Buttons Sampleモード
        - ボタンを押すと追加のシーンをロード・アンロードする
    - Character Sampleモード
        - キャラクターを特定の位置に移動させると追加のシーンをロード・アンロードする
    - Allow client side management (Host only)オプション
        - クライアントが任意のタイミングでシーンをロード・アンロード可能になる

![IDの作成](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/8324bf21-a25e-7d78-fb6a-5cc684fe262d.png)
![コピーするAppID](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/e40b3916-9a86-c027-dc75-dfb395f87b31.png)
![AppIDのペースト先](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/5fd3dd6f-b7bd-0ecd-3ee7-85359edc5a6f.png)
![Mainシーンの状態](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/fe728c4e-b7c2-936e-182c-24a749330d5e.png)

## サンプルの中身

シーンを管理するサンプルスクリプトはAssets>Scriptsにあります。主な機能は以下の通り。

CustomNetworkSceneManager.cs

- シーンの追加と削除
    - NetworkLinkedList<SceneRef>
        - ホスト・サーバーが必要なシーンを事前にキャッシュしておく

CustomSceneLoader.cs

- シーンをロードする
    - SceneManager.LoadSceneAsync（シーンのロード）はここで実行される

CustomSceneLoaderBase.cs

- シーンの状態を監視する
    - LateUpdateにて毎フレームチェック
    - 必要に応じて読み込み・破棄メソッドが呼ばれる

## おまけの機能

画面右のウィンドウをクリックするとログウィンドウが開き、UnityのConsoleウィンドウに近い情報を表示してくれます。
ビルドして動作確認することの多いオンラインマルチゲームでは非常に便利な機能です。
![ボタンの位置](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/f76b1b2c-e6b0-7111-a505-bca619af7efb.png)
![ログウィンドウ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2576800/59742488-0b42-eacf-5e15-c1683691780c.png)
WasmEdge コミュニティ ミーティングまであと 1 週間

来週火曜日の夜12:00 東京時間 参加を歓迎します:
https://community.cncf.io/events/details/cncf-wasmedgeruntime-community-presents-wasmedge-community-meeting-2022-09-06/

WasmEdgeは軽量かつ高性能なオープンソースWebAssemblyランタイムです。Second State社が中心となって開発し、現在はCloud Native Computing Foundation（CNCF）のサンドボックスプロジェクトの一つになっています。

* [WasmEdge Runtime](https://www.cncf.io/projects/wasmedge-runtime/) &mdash; Cloud Native Computing Foundation
* [コンテナ標準のOCI対応、クラウドネイティブなWebAssemblyランタイム「WasmEdge」が、CNCFのサンドボックスプロジェクトに採用](https://www.publickey1.jp/blog/21/ociwebassemblywasmedgecncf.html) &mdash; Publickey

WasmEdgeは主にC++で記述されており、公式のSDKを使うことで、C、Rust、Goなどで書かれたアプリケーションにWebAssemblyランタイムを組み込むことができます。

開発元のSecond State社は、このRust SDKの利用と開発を促進するために、期間限定の懸賞プログラムを発表しています。

We would like to build a small discussion group with topics like Serverless, cloud-native, K8s containers technologies and [find/ hire contributors who can help give features suggestions, raise issues on GitHub, or help translate](https://jobs.cncf.io/jobs/142577358-japanese-devrel-advocate-at-second-state-inc) WebAssembly blog articles and docs into Japanese. アドバイスをお願いします。
プログラミング言語 Egison

こちらを参考にしました。

https://qiita.com/yamashita1238/items/1cdaf51b7885a6f46b35

EgisonはVer.4から構文が大きく変わったので書いたのですが、内容はほぼ同じです。

## Egison とは？

Egison (エギソン) は強力なパターンマッチを特徴とするプログラミング言語です。
2011年に[江木 聡志さん](https://www.egison.org/~egi/)が東京大学大学院修士課程で開発を始めました。

### インストール

[公式サイト](https://www.egison.org/ja/)のドキュメントタブからインストール方法にたどり着けます。

#### Homebrew を使ったインストール

macOS で Homebrew を使っている方は

```sh
$ brew update
$ brew tap egison/egison
$ brew install egison egison-tutorial
```

でインストールできますが、ライブラリのディレクトリがおかしい様で、このままでは使えませんでした。
egisonは`/usr/local/lib`にライブラリを探しに行く様ですが、homebrewでインストールしたら`/opt/homebrew/lib/`にライブラリが入ります。(人によって違うかもしれません)
仕方ないので`/usr/local/lib`にシンボリックリンクを貼ります。

```sh
cd /usr/local/lib
ln -s /opt/homebrew/lib/egison
```

egison-tutorialも同様の問題があるので、同様にシンボリックリンクを貼ります。

```sh
mkdir /usr/local/lib/egison-tutorial
cd /usr/local/lib/egison-tutorial
ln -s /opt/homebrew/lib/egison/lib
```

後は
```sh
$ egison
```
 
で Egison インタープリターが立ち上がります。
チュートリアルも使えます。


```sh
$ egison-tutorial
```

[オンラインチュートリアル](http://try.egison.org)も使えます。

### map 関数の例

haskellの場合

```haskell
mymap :: (a -> b) -> [a] -> [b]
mymap _ [] = []
mymap f (x:xs) = f x : mymap f xs
```

```haskell
*Main> mymap (*2) [2,3,4]
[4,6,8]
```

標準ライブラリにmapがあるので、ここではmymapとしています。
リストの先頭に対する関数適用と残りに対して再帰的に処理する事と、空リストの場合の記述を書いています。
haskellは宣言型プログラミング言語ではあるものの、これはやや手続き的な匂いがしますね。

egisonの場合

```haskell
def mymap f xs :=
  matchAll xs as list something with
  | _ ++ $x :: _ -> f x

> mymap (* 2) [2,3,4]
[4, 6, 8]
```

listが空かどうかという場合分けをすることなく map を定義できています。
haskellより更に宣言的と言えるでしょう。

`as`と`with`に挟まれた箇所をマッチャーと言います。
ここでは`list something`がマッチャーで、なんらかのリストとしてパターンマッチします。

文字列のリストとしてパターンマッチするときは `list string` のようにマッチャーを使い分けることができます。

### adjacentMap の例

リストの隣接する 2 要素を二引数関数に渡していって、結果をリストで返す adjacentMap 関数です。

haskell では以下のようになるでしょうか。

```haskell
adjacentMap :: (a -> a -> a) -> [a] -> [a]
adjacentMap _ [] = []
adjacentMap _ (_:[]) = []
adjacentMap f (x : y : zs) = f x y : adjacentMap f (y : zs)
```

```haskell
*Main> adjacentMap (*) [1, 2, 3, 4, 5]
[2,6,12,20]
```

場合分けが増えてしまいますね。
一方、Egisonでは以下のようにより直感的です。

```haskell
def adjacentMap f xs :=
  matchAll xs as list something with
  | _ ++ $x :: $y :: _ -> f x y
```

```haskell
> adjacentMap (*) [1, 2, 3, 4, 5]
[2, 6, 12, 20]
```


### もうちょっと複雑な例

↓こちらを参考
[ポーカーの役判定](https://www.egison.org/ja/demonstrations/poker-hands.html)

最初の２つのdef `suit`と`card`がマッチャーで、トランプのカードに当たるデータをどのようにしてパターンマッチするのかを定義しています。

関数`poker`で役を判定します。
この関数は一つの大きなマッチ式で定義されています。
ポーカーの役が全て簡潔なパターンで記述されています。

ストレートフラッシュ(同じスートで数字が連続する5枚のカードで構成された役)

```haskell
[card $s $n, card #s #(n-1), card #s #(n-2), card #s #(n-3), card #s #(n-4)]
    -> "Straight flush"
```

フルハウス(5枚の手札のうち3枚が同じ数字で、残り2枚もまた数字が揃っている役)

```haskell
[card _ $m, card _ #m, card _ #m, card _ $n, card _ #n]
    -> "Full house"
```

のように記述されています。
「手札のうち 3 枚の数字が m で残り 2 枚の数字が n ならフルハウス」と素直に読めると思います。
【Rails】開発環境で見たい情報を表示する

# 目的
Webアプリ開発中に、ページ遷移や`form_with`で送った情報が正しいかを確認することで自分が書いたコードの確認やエラー解消のヒントに繋がります。

# `debug`メソッドを使う

今回は例として`params`ハッシュを表示します。
`params`ハッシュを表示させることで、ページが持つ情報を見ることができます。

ページ内に`params`ハッシュを表示させるには、`debug`メソッドを使用します。
例えばapplication.html.erb内で下記のコードを加えることで、`params`ハッシュを取得することができます。

```ruby:app/views/layouts/application.html.erb
<%= debug(params) if Rails.env.development? %>
```
ここで、`if Rails.env.development?`と条件を付けることで、この式がtrueのとき、つまり開発環境のときのみ表示させています。

# 他には何を見る？

**ログイン中ユーザーの情報を見る場合**
これにより、ログイン中のユーザーが認証されたか(activatedカラムがtrueか)や、記憶トークンを保持しているか(remember_digestカラムに値が入っているか)を確認することができます。

```ruby
<%= debug(@current_user) if Rails.env.development? %>
```


**cookies情報の一部をみる**
cookies情報を全て表示させることはおすすめしません。
ここで伝えたいことは、`debug`メソッドの引数に適切な式を入れることで自分が必要な情報を取得できるということです。
今回は認証トークンであるremember_tokenを表示させることで、ヘルパーやモデルで定義したメソッドがきちんと動いているかを確認しました。
```ruby
<%= debug(cookies[:remember_token]) if Rails.env.development? %>
```

# 引用元

[Railsチュートリアル 第7章](https://railstutorial.jp/chapters/sign_up?version=6.0#sec-rails_environments)
ナチュラルキーとサロゲートキー

分析モデリングした際に、
たとえばあるユースケース
「顧客を(一意な顧客番号で)検索する」みたいなユースケースがあったとき、
【顧客】てエンティティには【顧客番号】という属性が必要です。

※この顧客番号ってのは　DBを意識した主キーなるものではないことに注意してください。

これわたしも最初モデリングに慣れてない頃は、分析段階でDBを意識してしまってたんですが、
本来の分析モデリングでは以下の詳細は考えません。

・言語はなににするのか
・DBはどれ使うか　などなど

あくまでも分析段階では、ユースケース(つまり機能要求)を満たすために
何が　必要なのか？を明らかにするだけです。

なので上記の顧客番号は、「顧客を(一意な顧客番号で)検索する」という、
ユースケースシナリオを実現するために必要な属性というだけです。

そして分析モデリングがある程度まとまったら、次に設計にいきます。
この時RDBを使うということになったとしましょう。

その際にこの顧客番号は、一意なために顧客テーブルの候補キーといえますね。

①そこでこれをそのまま顧客テーブルの主キーとして使うのか　→　ナチュラルキー手法
②それとも別に新たに主キーを定義してあげて、顧客番号にユニーク制約つけるのか　→　サロゲートキー手法

この２通りの手法があります。

一見、①の方が素直に見えます、、、よね？

しかもドメインモデルとテーブルの見た目が乖離しないからシンプルって利点があります。
逆に②はドメインモデルとテーブルの見た目が乖離して見えてしまうて欠点があります。

ただサロゲートキーにも利点はありますし、それは同時にナチュラルキーの欠点でもあることです。

結論から言うと　
変化に強いのがサロゲートの利点、　変化に弱いのがナチュラルキーの欠点です。

ナチュラルキーはその特性上UIに近い存在だからか、
結構UI側に振り回されて変更が入りやすいって特性があります。
しかしながら主キーはその特性上、更新してはいけないという制約があります。
なので結果的に仕様変更に弱いし、複雑になってしまう恐れがあります。

対して、サロゲートキーは内部で自動的に一意な値を振る特性があるので
特にUIとかの都合に振り回されず、結果的に仕様変更などの変化に対して強く、
シンプルなテーブル設計の維持がしやすくなります。

さらに１つ追加すると、
ドメインモデルとテーブルのミスマッチの解消にはサロゲートキーが好ましいといわれています。

理由は、サロゲートキー自体はシンプルなものなので、
DAOパターンや　RailsなどのActiveRecordを使うことで、
ドメインモデルとテーブルのミスマッチを容易に解消できます。

以上のことから、顧客番号なるものが変更される可能性がほぼないならナチュラルキー、
そうでないなら最初からサロゲートキーを用いることが後々の変化にも対応できることがうかがえます。
[Houdini学習9日目]Group geometry nodeで選択範囲が出ないとき

例えば、gridのある範囲と物体が重なる範囲だけを
groupノードで選択するというとき、

重なる範囲が選択された状態にならないということが頻出する。
毎回原因を忘れて時間を浪費しているので書き残しておく。

## 原因
ノードは下記の方法で作れるが、
groupノードを2つ目の方法で作った場合に限りこの問題が起きる。
>１．Scene Viewまたは、Network viewでTabキー押下
２．Network viewで右クリック

現在使用しているテキストでも１番の案内しかなかったのだが、
たまたまNetwork viewで右クリックしたらTAB Menuがでてくることを知って以来
右クリックで作るやり方を愛用していた。
２番目の方法がそもそも非公式なものなのかもしれない。

これからはTabキーからノードを作る癖をつけよう。。。
go installしたバイナリをscratchイメージで動かす場合の注意点

# TL; DR

- webサーバー等netパッケージを使っているバイナリを `go install` する場合は `CGO_ENABLED=0` をつける
    - 付けないと `no such file or directory` と出てしまう
    - netパッケージをimportしたバイナリはダイナミックリンクでビルドされてしまうのが原因

# はじめに

[gRPC UI](https://github.com/fullstorydev/grpcui) [^1]のバイナリをマルチステージビルドしたら、`no such file or directory` と出て実行できませんでした。

```bash
$ docker build .
Sending build context to Docker daemon  9.216kB
...
Successfully built 53b474247144
$ docker run -it --rm 53b474247144
exec ./grpcui: no such file or directory
```

# 原因

goのバイナリは通常スタティックリンクで生成されますが、netパッケージを使う場合のみダイナミックリンクでビルドされてしまうのが原因でした。
（ダイナミックリンクなのでscratchイメージに持っていくと実行時にライブラリが無くて動かなくなってしまいます）

`CGO_ENABLED=0` でC非依存のスタティックリンクリンクを作成すれば、scratchでも動くようになりました。

```Dockerfile
FROM golang AS builder
ARG CGO_ENABLED=0
RUN go install github.com/fullstorydev/grpcui/cmd/grpcui@latest

#...
```

参考にさせていただいた記事

https://qiita.com/4486/items/915e9e4c77f012c365ff

https://qiita.com/KEINOS/items/739f83cb9ddfed43404b


[^1]: gRPC UIは、UI上で手軽にgRPCリクエストを送れるwebアプリ(イメージはSwaggerのgRPC版？)です。
40代おっさんAppSheetを学ぶ

## 本記事について

この記事はプログラミング初学者の私が学んでいく中でわからない単語や概要を分かりやすくまとめたものです。
もし不正などありましたらコメントにてお知らせいただければ幸いです。

## ノーコードとは何か

・コードを全く書かずにアプリケーションを開発する仕組み
・あらかじめさまざまな機能を設定する仕組みを用意しておき、それらの設定を行うことでアプリケーションが完成するようにしている

### 業務用アプリはデータがすべて

・ノーコードアプリがターゲットとするのは業務アプリ
・誰でも簡単に利用できるようになっていることが重要
・業務用アプリは基本的にデータをいかに扱うかがすべて
・データの基本操作は一般的にCRUD,Create,Read,Update,Deleteさえできれば使える

### ノーコードアプリはスタンドアロンでない

・ノーコード開発環境で作られるアプリは、あらかじめデータアクセスの為のシステムが用意されている。それをもとにして個々のアプリが作れる
・基本的にシステムはノーコードサービスのクラウド上にあり、アクセスして必要な処理を呼び出す

## ノーコードのメリット

・圧倒的な開発スピード
・アプリのクオリティが高い

## ノーコードのデメリット

・用意されている機能しか使えない
・サービスに縛られる
・互換性がない

## AppSheetとは

・Googleが提供するノーコードサービス
・他を圧倒する開発スピード
　（作成、更新、削除を行うアプリなら数分で可能）
・Googleサービスとの連携が可能
・無料で使える（有料もある）

### AppSheet利用に必要なもの

・Googleアカウント
・Webブラウザ

## 参考資料

<https://www.amazon.co.jp/Google-AppSheet-%E3%81%A7%E3%81%AF%E3%81%98%E3%82%81%E3%82%8B%E3%83%8E%E3%83%BC%E3%82%B3%E3%83%BC%E3%83%89%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0-%E6%B4%A5%E8%80%B6%E4%B9%83-ebook/dp/B098W4XDBB>
【Ruby】文字列がintegerだけで構成されているかどうかを判定する方法

## 環境
Rails 6.0.1
Ruby 2.6.3
PostgreSQL 11.16


## 判定方法①


```ruby
phone_number = '090-1234-5678'
nil != (phone_number =~ /\A[0-9]+\z/)
# => false

phone_number = '09012345678'
nil != (phone_number =~ /\A[0-9]+\z/)
# => true
```


## 判定方法②

①よりコードをみたとき直感で分かる

```ruby
phone_number = '090-1234-5678'
phone_number.match?(/\A[0-9]+\z/)
# => false

phone_number = '09012345678'
phone_number.match?(/\A[0-9]+\z/)
# => true
```

## 参考

https://qiita.com/niwasawa/items/ba6c432fcc3d04fc18c9
レイクハウスはどのようにしてディスカバリーとコラボレーションを改善するのか？

[How does the lakehouse improve data discovery and collaboration? \| Databricks on AWS](https://docs.databricks.com/lakehouse/collaboration.html)の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

Databricksは様々なデータユーザーが大規模なデータを発見、分析するのを支援することで、企業が洞察に至る時間を短縮するためにUnity Catalogを設計しました。データスチュワードは、Unity Catalogで様々なエンドユーザーのチームに対してデータ資産に対するアクセスをセキュアに許可することができます。すると、これらのユーザーは、チーム横断で共有できる派生データセット、モデル、ダッシュボードを作成するために、SQL、Pythonのような様々な言語やツールを活用することができます。

# 大規模システムにおける権限管理

Unity Catalogは、カタログ、データベース、テーブル、ビューに対する権限をユーザーグループに割り当てる統合された場所を提供します。権限やメタストアはワークスペース横断で共有されるので、管理者がアイデンティティプロバイダーから同期されるグループに一度セキュリティ権限を設定すると、どのDatabricksワークスペースにログインしたとしても、エンドユーザーは適切なデータにのみアクセスできることを認識できます。

また、Unity Catalogを用いることで、管理者はクラウドストレージインフラストラクチャで権限を格納、共有するセキュアな手段であるストレージ資格情報を定義できるようになります。企業内のパワーユーザーに対してこれらのセキュリティ保護可能なオブジェクトに対する権限を付与し、クラウドオブジェクトストレージの格納場所に対して外部ロケーションを定義することで、データエンジニアはクラウドアカウントコンソールで強い権限を与えることなしに、新たなワークロードに対してセルフサービスすることができます。

# Databricksにおけるデータの発見

データエクスプローラを用いることで、ユーザーはUnity Catalogで利用可能なデータオブジェクトをブラウズすることができます。データエクスプローラは、ユーザーがクエリーできる権限を持っているカタログ、データベース、テーブル、ビューしか参照できないように、Unity Catalog管理者によって設定された権限を使用します。ユーザーが興味のあるデータセットを見つけると、フィールド名や型、テーブルを確認し、個々のフィールドのコメントを読み、データのサンプルをプレビューすることができます。また、データがいつどのように変更されたのかを理解するためにテーブルの完全な履歴を確認することもでき、リネージュ機能によって、ユーザーは特定のデータセットがどのように前段のジョブから生成され、後段のジョブでどのように使用されているのかを追跡することができます。

また、ストレージ資格情報と外部ロケーションもデータエクスプローラに表示されるので、それぞれのユーザーは利用可能なロケーションやリソースに渡るデータを読み書きするために必要な権限を完全に理解することができます。

# レイクハウスによるプロダクションへの到達時間の短縮

DatabricksではSQL、Python、Scala、Rのワークロードをサポートしており、様々なスキルセットや技術的バックグラウンドを持つユーザーが、分析による洞察を引き出すために自身の知識を活用することが可能となります。プロダクションのジョブを定義するためにDatabricksでサポートされているすべての言語を使用することができ、ノートブックでは言語を組み合わせて活用することができます。これは、ほぼ工数なしに、SQLアナリストによって記述された最終ステップのETLクエリーをプロダクションのデータエンジニアリングコードにプロモーションできることを意味します。企業のペルソナによって定義されたクエリーとワークロードは同じデータセットを活用するので、他のチームとコードや結果を共有する前にフィールド名を一致させたりする必要はなく、ダッシュボードは常に最新の状態となります。同一のスケーラブルなクラウドインフラストラクチャによって下支えされ、同じ整理されたデータソースに対して定義されているので、コード、ノートブック、クエリー、ダッシュボードすべてをセキュアに共有することができます。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
アプリ起動中にダークモード変更を検知する方法

## はじめに
外観モードによって分岐させる方法はよく見かけますが、
アプリ起動中に検知する方法をあまり見かけなかったので記事に残しておきます。
(あるけど、複雑だったり...)

# 外観モード変更を検知し、プロパティの値を分岐させる
#### 初期設定
```Swift
class ViewController: UIViewController {
    let label = UILabel()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.text = UITraitCollection.current.userInterfaceStyle == .light ?
                     "ライトモードだよー" :
                     "ダークモードだよー"
    }
}
```

#### 外観モード変更の検知
```Swift
class ViewController: UIViewController {
    let label = UIlabel()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        label.text = UITraitCollection.current.userInterfaceStyle == .light ?
                     "ライトモードだよー" :
                     "ダークモードだよー"
    }
    
    // ↓↓追記
    override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
        super.traitCollectionDidChange(previousTraitCollection)
        
        // 再度設定する
        label.text = UITraitCollection.current.userInterfaceStyle == .light ?
                     "ライトモードだよー" :
                     "ダークモードだよー"
    }
}
```

# UIColorの対応(おまけ)
#### UIColor(dynamicProvider: )で定義する
```Swift
class AppTheme {

    static var primaryTextColor = UIColor { uiTraitCollection in
        switch uiTraitCollection.userInterfaceStyle {
        case .light:
            return .blue
        case .dark:
            return .yellow
        default:
            return .blue
        }
    }
}
```
[init(dynamicProvider:)](https://developer.apple.com/documentation/uikit/uicolor/3238041-init)でインスタンス化しておくと、
外観モードに変化があった際に自動で対応してくれるようです。

#### ViewController側でセット
```Swift 
class ViewController: UIViewController {

    let label = UILabel()

    override func viewDidLoad() {
        super.viewDidLoad()
        label.text = "hogehoge"
        label.textColor = AppTheme.primaryTextColor
    }
}
```

## 最後に
最後まで読んでいただきありがとうございました。


#### 追記
記事の公開当初、UIColorの対応をアンチパターンで書いていました。
Twitterで指摘してくださった２名の方、ありがとうござました🙇‍♂️
今どきの分析フローを考察する(DWH内のお話し) 

# 今どきの分析フローを考察(DWH内のお話し)

少し前に`dbt lab`の`Developer Blog`で[How We Structure our dbt Projects](https://docs.getdbt.com/blog/how-we-structure-our-dbt-projects)を読んだため、そのメモと私の思想も組み込んで備忘録とします。

間違っているよや言っていることがよくわからないなどありましたらコメントお願い致します。

この記事によるとDWH(データウェアハウス内)では3つ(4つ)のスキーマが存在するべきとしています。各層の名称は以下のようになります。1から4に数字が進むにつれてデータが整備されていきます。またこれから行う作業はdbtを使用して行うことがおすすめされています。なぜならデータの変換(T)を行うことに特化したサービスこそがdbtだからです。dbtの良さについては別途記事にします。この記事もdbtを使用することを前提に話を進めていきます。

1. Source
2. Staging
3. (Intermediate)
4. Marts

では各層の簡単な説明及び実施内容等をつらつらと記載します。
## 1. Source

各APIやデータやサードパーティ経由で取得したデータを保持しておくレイヤ―になります。
とりあえず取得したデータはここに突っ込んでおけばよいと思います。

説明は以上！です。
Sourceの定義やテストなどの設定はyamlファイルを作成し、そこで行います。

## 2. Staging

Source層のテーブルと1対1になるように設計されます。基本的にSource層に格納されているデータの簡単な整備を行うレイヤーになります。下に、実際行う一例を挙げます。

- カラムのリネームを行う
- データタイプやタイムゾーンを修正する
- 空文字を`NULL`に置き換えるといった簡単なクレンジングを行う
- オブジェクトのフラット化(構造化)等を行う
- ユニークかつ非NULLであるプライマリーキーの設定を行う
- 重複しているレコードの削除を行う
- サロゲートキーの作成を行う(datavaultで使用します)

Staging層では、データソースが複数ある場合は、その都度ディレクトリを作成します。

また、sqlファイルの命名規則として次の3つが代表的です。

- stg_<ソース名>_<オブジェクト名>.sql
    - オブジェクトのモデル
    - 基本的にビューで持たせる(パフォーマンスが欲しい場合はテーブルで保持する)

- scr_<ソース名>.yml
    - `source` の定義を行う(テストやドキュメントなど)

- stg_<ソース名>.yml
    - `models`の定義を行う(テストやドキュメントなど)

また変換作業を行う際は`base model`を使用することが推奨されています。`base model`とはカラムのリネームやキャストなどを専門に行うsqlになります。下記はサンプルクエリになります。

```sql
    with source as (

        select * from {{ source('braintree', 'payments') }}

    ),

    renamed as (

        select
            id as payment_id,
            order_id,
            convert_timezone('America/New_York', 'UTC', createdat) as created_at,
            ...

        from source

    )

    select * from renamed
```

## 3. (Intermediate)

複雑な処理を行う際に使用されるのはこの中間スキーマです。

以下は私の雑感になります。
最近datavaultというものが流行っているようです。最近その存在を知りました。まだまだ不勉強であるので詳しくを分かりませんがお話を聞く限り、このintermediate層にこの処理を行う(行おうとしている)企業があるように感じます。datavaultについて学んでから個々の雑感は再度書き直したいです。


## 4. Marts

ビジネスの実態に沿ったテーブルを作成します。ここでは各部署・テーマごとにディレクトリを作成します。本記事ではファクト・ディメンジョンモデルを例に紹介します。(ファクト・ディメンジョンモデルの説明は割愛します)基本的にこのモデルでは文字通りファクトとディメンジョンが存在します。

- fct_<ほげほげ>
    - ザックリいうと縦長いテーブルです。トランザクションやセッション記録、注文履歴など変更できないイベントログがこれにあたります。
- dim_<ほげほげ>
    - ザックリいうと横長いテーブルにあたります。各実態の変更しうる詳細なレコードが記録されています。製品、従業員、企業情報などがこれにあたります。


## まとめ
このようにレイヤーごとに定義するべきことがあるようですね。個人的にdbtは非常に便利な変換ツールなのでより注目していきたいと思います。


## 参考文献
- [How We Structure our dbt Projects](https://docs.getdbt.com/blog/how-we-structure-our-dbt-projects)
契約による設計(Design By Contract)

先日、SOLID原則のひとつの【リスコフの置換原則】に触れた際に、
【契約による設計DbC】を改めて重要視しようと意気込み、かつ後のテストもしやすそうだろうなぁーと思ったので、
会社のVPでのソースコードの主要メソッドに契約　つまり

・事前条件(呼び出し側がメソッドを呼び出す前に満たすべきこと)

・不変条件(呼び出される側がメソッドの実行前に満たしておくべき条件→フィールドの値がセットされて状態が整ってるか？　コンストラクターで初期化することがこれに相当します。)

・事後条件(メソッドが実行されたあとどうなっているのか？　どんな戻り値なのか？　どんな例外が投げられてくるのか？etc)

の３つを残しておいてみてます。

※(なお今回のドメインには出てきませんでしたが、
分析モデルの継承関係の所を設計フェーズでジャッジをする際に、
このDbCをもとに正しい継承関係なのかジャッジします。
もしもそれに反してたらサブタイプをスーパータイプとして扱うというポリモーフィズムは不可能です。)



あくまでもアジャイルチックに最初は正常フローのみ作ってるから、
後に異常フローを考察した際に、この事後条件などは追記事項があるだろうけども、
一旦は「あとからまたこの部分修正してブラッシュアップしよう！」てマインドでいます。
この

また分析モデリングはきちんと行うが、
設計モデリングはやりすぎず、
詳細の不明なところだけシーケンス図描いたりして、ソースコード自体をドキュメントとして管理してみてる。
クラス名や変数名、メソッド名をわかりやすくするだけでなく、
DbCもメソッドに残してあげるのが理想だなと実感しました。
その方があとでテストする際に、なにをテストし、
何を持ってしてテストが通ったといえるのかも明確に説明できるし。

実際のプロジェクトではすべてのメソッドにDbCを書くなんてことは工数的に無理があるのかもしれないけれど、
重要な箇所にはきちんと定義し、かつ　仕様変更が入ったらなる早でDbCもメンテをしてあげることが望ましいのでは？

と思う次第でした。
Windows上でRustのクロス環境の作成(ARMv7 Linux)

## 概要

- Windows環境でRustのクロス開発環境を用意する

- ターゲットはarmv7-unknown-linux-gnueabihf(Linux用バイナリ)とする

- WSL2、docker、msys2等は使用しない

- プロジェクト作成後はVSCodeで編集、ターミナルでビルドする想定です。

- この環境で作成できるバイナリはインストールしたARM用のToolchainのバージョンに依存します。(サポートしているglibc等のバージョンに注意が必要です)
  
  
  
  Rustでサポートされているtarget、arm Developerで配布されているWinodws用のPrebuildのtoolchainの組み合わせであれば、簡単に環境構築が可能です。(GCC + msys2のクロス環境よりもかなり楽です。)

## 環境構築

### 1. Rustのインストール

https://static.rust-lang.org/rustup/dist/x86_64-pc-windows-msvc/rustup-init.exe

最新版を確認

```batch
rustup update
```

### 2. rustupでARMv7用のターゲットのインストール

```batch
rustup target add armv7-unknown-linux-gnueabihf
```

### 3.  ARMv7のToolchain(Windows用)のインストール

https://developer.arm.com/downloads/-/arm-gnu-toolchain-downloads

gcc-arm-11.2-2022.02-mingw-w64-i686-arm-none-linux-gnueabihf.exe

インストーラ形式のファイルをダウンロードします。（ファイルサイズが小さい上に環境変数の登録まで行ってくれるため）

インストール終了時にPATHを追加するオプションを選択してください。

ユーザー環境変数のPATHに以下のディレクトリが追加されていることを確認してください。

"C:\Program Files (x86)\Arm GNU Toolchain arm-none-linux-gnueabihf\11.2 2022.02\bin"

### 4. /Users/ユーザー名/.cargo/configの設定

エクスプローラで/Users/ユーザー名/.cargoのフォルダを開きます。

```batch
explorer %HOMEPATH%\.cargo
```

configを新規作成します。

.cargo/config

```ini
[target.armv7-unknown-linux-gnueabihf]
linker = "arm-none-linux-gnueabihf-gcc"
```

## プロジェクトの作成

cargo new コマンドでプロジェクトを作成します

```batch
cargo new test(プロジェクト名)

cd test
```
以下のファイルが作成されます。
```Rust
// main.rs
fn main() {
    println!("Hello, world!");
}
```

ターゲットを指定してビルドを行います

```batch
cargo build --target armv7-unknown-linux-gnueabihf --release
```

ファイルをstripします

```batch
arm-none-linux-gnueabihf-strip.exe .\target\armv7-unknown-linux-gnueabihf\release\test
```

これでファイルサイズがかなり小さくなります。

一連の処理をバッチファイルにまとめたものが以下になります。

build.bat

```batch
set target_arch=armv7-unknown-linux-gnueabihf
cargo build --target %target_arch% --release
set THIS_PATH=%~dp0
for %%1 in ("%THIS_PATH:~0,-1%") do set FOLDER_NAME=%%~nx1
arm-none-linux-gnueabihf-strip.exe .\target\%target_arch%\release\%FOLDER_NAME%
move .\target\%target_arch%\release\%FOLDER_NAME% ./
```

カレントのディレクトリ名を取得する処理は

https://qiita.com/k1tajima/items/ebf4145367ef268dc124

を利用させていただきました。
ポートを調べて止める

使ってるポートを調べる

```
sudo netstat -ntlp | grep LISTEN
```

  
特定のポートを調べる
```
sudo netstat -ntlp | grep :443
```


ポートを止める
```
sudo kill -TERM プロセスの番号
```


※443また動かすなら
```
systemctl start httpd
```

あとファイアウォールとかも気にする
create-dmgを使ったdmgの作成

## 概要
- [create\-dmg/create\-dmg](https://github.com/create-dmg/create-dmg)を使って、下記のような構成のdmgを作成する。

![image](https://i.imgur.com/oeCLMp7.png)

## 参考
- [create\-dmg/create\-dmg](https://github.com/create-dmg/create-dmg)
- 決まったフォーマットのdmgならこれもあり？（私自身は試してないです）
    - [LinusU/node\-appdmg](https://github.com/LinusU/node-appdmg)

## 実践
### 前提
- [create\-dmg/create\-dmg](https://github.com/create-dmg/create-dmg)の通りに進めていけばOK。
- またフォルダ構成は下記とする。
    - `seticon.swift`に関しては後述。

![](https://i.imgur.com/h1K6VHl.jpg)

### Homebrewでインストール

```shell
brew install create-dmg
```

### create-dmgの実行

- `--hide-extension`は動作していない？

```shell
cd /Users/ikeh/Downloads/DMG_Test

create-dmg \
  --volname "Application Installer" \
  --background "installer_background.jpg" \
  --window-pos 200 120 \
  --window-size 812 542 \
  --icon-size 100 \
  --icon "QuickImageUploader.app" 200 190 \
  --hide-extension "QuickImageUploader.app" \
  --app-drop-link 600 185 \
  "Application-Installer.dmg" \
  "source_folder/"
```

![](https://i.imgur.com/tslVkJC.jpg)


### dmgのアイコン設定
- 私の環境では`--volicon`が動作していないように見えた。

>https://github.com/create-dmg/create-dmg/blob/master/README.md
>--volicon <icon.icns>: set volume icon

- 代わりに下記の`seticon.swift`でアイコンを設定できる
    - [Replace volume file's icon \#132](https://github.com/create-dmg/create-dmg/issues/132)

```shell
swift seticon.swift Icon_1024px.png Application-Installer.dmg
Set Application-Installer.dmg icon to Icon_1024px.png [(1024.0, 1024.0)]
```

- `seticon.swift`

```swift
import Foundation
import AppKit

// Apple deprecated their command line tools to set images on things and replaced them with a
// barely-documented swift function.  Yay!

// Usage: ./seticon /path/to/my.icns /path/to/some.dmg

let args = CommandLine.arguments

if args.count != 3 {
    print("Error: usage: ./seticon /path/to/my.icns /path/to/some.dmg")
    exit(1)
}

var icns = args[1]
var dmg = args[2]

var img = NSImage(byReferencingFile: icns)!

if NSWorkspace.shared.setIcon(img, forFile: dmg) {
    print("Set \(dmg) icon to \(icns) [\(img.size)]")
} else {
    print("Setting icon failed, don't know why")
    exit(2)
}
```

## マウント時にフォルダを開く設定について
- 最近まで`bless`があったが、現在はdeprecatedになっている。
- またこのオプションを指定しなくても以前通り自動でフォルダは開くみたい。

>https://github.com/create-dmg/create-dmg/blob/master/README.md
>--bless: bless the mount folder (deprecated, needs macOS 12.2.1 or older, #127)

>https://github.com/create-dmg/create-dmg/issues/127
>I'm updating to 12.3 to test that one. Just checked that not using that option does not seem to affect on the DMG opening in the Finder when mounted.
Reactのテスト(Jest)でWarning(ReactDOM.render is no longer supported in React 18)が発生する

# はじめに

Jestのテストを書いていて気になった個所があったので修正箇所をまとめています

# 問題

Reactのテストを実行すると赤文字で以下のエラーが出力されるようになりました

```
ReactDOM.render is no longer supported in React 18. Use createRoot instead. Until you switch to the new API, your app will behave as if it's running React 17. Learn more: https://reactjs.org/link/switch-to-createroot
```

テストは問題なく通るのですが、warningでログに色々表示されてしまうので非表示にしようと思いました

# 解決方法

`setupTests.ts`を以下に変更したところwarningが消えました

```ts:setupTests.ts
import '@testing-library/jest-dom';

const originalError = console.error;
beforeAll(() => {
  console.error = (...args) => {
    if (/Warning: ReactDOM.render is no longer supported in React 18./.test(args[0])) {
      return;
    }
    originalError.call(console, ...args);
  };
});

afterAll(() => {
  console.error = originalError;
});
```


# 参考

https://stackoverflow.com/questions/71685441/react-testing-library-gives-console-error-for-reactdom-render-in-react-18
Zabbix Server 6.2をAzure VMにインストールする（Ubuntu20.04)

# この記事の目的
検証用Zabbixサーバーを建てる  
Kubernetesが監視できるようになったと聞いて、テストしてみたかった

# AzureVMの構成
適当につくる
| 項目 | 設定値 |
| ---- | ---- |
| VM Image | Ubuntu 20.04 |
| VM Size | Standard B2s |
| Disk | Standard SSD |
| NIC | グローバルIPをつける <br> SSHとHTTPを自分のグローバルIPのみNSGで許可する|

# Zabbixのインストール
```
# とりあえずアップデート
apt update -y && apt upgrade -y

# MySQLのインストール
apt install -y mysql-server

# 日本語の追加
dpkg-reconfigure locales
-> ja-jpのUTF8を追加する

# apache2の停止
systemctl stop apache2
systemctl disable apache2
```
あとはzabbixの公式手順どおり
```
wget https://repo.zabbix.com/zabbix/6.2/ubuntu/pool/main/z/zabbix-release/zabbix-release_6.2-1%2Bubuntu20.04_all.deb
dpkg -i zabbix-release_6.2-1+ubuntu20.04_all.deb
apt update
apt install zabbix-server-mysql zabbix-frontend-php zabbix-nginx-conf zabbix-sql-scripts zabbix-agent

mysql -uroot -p
※passwordはpassword
mysql> create database zabbix character set utf8mb4 collate utf8mb4_bin;
mysql> create user zabbix@localhost identified by 'password';
mysql> grant all privileges on zabbix.* to zabbix@localhost;
mysql> set global log_bin_trust_function_creators = 1;
mysql> quit;

zcat /usr/share/doc/zabbix-sql-scripts/mysql/server.sql.gz | mysql -uzabbix -p zabbix

mysql -uroot -p
※passwordはpassword
mysql> set global log_bin_trust_function_creators = 0;
mysql> quit;
```

/etc/zabbix/zabbix_server.confを編集する
```
vi /etc/zabbix/zabbix_server.conf
---
+ DBPassword=password
---
```

# Nginxの設定
適当にNginxの設定をします
```
vi /etc/nginx/nginx.conf
---
 ##
 # Virtual Host Configs
 ##

+ include /etc/zabbix/nginx.conf
---
```

```
vi /etc/zabbix/nginx.conf
listen 8080; -> listen 80;
server_nameのコメントアウトを外す
```

# サービスの起動
```
systemctl restart zabbix-server zabbix-agent nginx php7.4-fpm
systemctl enable zabbix-server zabbix-agent nginx php7.4-fpm
```

# VMのグローバルIPに接続すれば接続できるはず。
http://<your VM GlobalIP>/
React(Jest)でAxiosをMockしてPOSTのテストを行う

# はじめに

Reactでフロントを書き始めて1ページが終わりテストのフェーズに入りました
そしていきなりつまづいたのでAxiosのテストについてまとめます

# 問題

ReactでAxiosを使って`email`と`password`をPOSTして、`name`を受け取るリクエストを作成しました
テストをJest(reatc-testing-library)と、testing-library/react-hooksを利用して以下のように書きました

Axiosはモックにして常に同じ結果を返すようにしました

```tsx:useAuth.tsx
import { renderHook, act } from "@testing-library/react-hooks";
import { useAuth } from "../hooks/useAuth";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";

const response = {
  data: {
    name: "Tarou",
  },
};

const mock = new MockAdapter(axios);
mock.onPost(`http://localhost:8080/sign_in`).reply(200, response);

const mockedNavigator = jest.fn();
jest.mock("react-router-dom", () => ({
  ...jest.requireActual("react-router-dom"),
  useNavigate: () => mockedNavigator,
}));

describe("useAuthlogin", () => {
  it("トップページに遷移すること",　() => {
    const { result } = renderHook(() => useAuth());

    act(() => {
      result.current.login("test@example.com", "password");
    });

    expect(mockedNavigator).toHaveBeenCalledWith("/");
  });
});
```

テストではリクエストがとおると`/`に`useNavigate`を利用してページ遷移するので、ページ遷移が行われているかテストしています。しかしこのコードでは`case 0`とエラーになり、遷移が行われていないことで失敗してしまいました

# 解決方法

Axiosは非同期なので、非同期の処理が終わる前に`expect`の評価が行われているためページ遷移が行われていませんでした
`login`の処理の実行を`async/await`で待ってから`expect`でテストをすると通りました

```tsx:useAuth.tsx
import { renderHook, act } from "@testing-library/react-hooks";
import { useAuth } from "../hooks/useAuth";
import axios from "axios";
import MockAdapter from "axios-mock-adapter";

const response = {
  data: {
    name: "Tarou",
  },
};

const mock = new MockAdapter(axios);
mock.onPost(`http://localhost:8080/sign_in`).reply(200, response);

const mockedNavigator = jest.fn();
jest.mock("react-router-dom", () => ({
  ...jest.requireActual("react-router-dom"),
  useNavigate: () => mockedNavigator,
}));

describe("useAuthlogin", () => {
  it("トップページに遷移すること", async () => {
    const { result } = renderHook(() => useAuth());

    await act(async () => {
      await result.current.login("test@example.com", "password");
    });

    expect(mockedNavigator).toHaveBeenCalledWith("/");
  });
});
```

# おわりに

Jestを始めて書いたのがこのテストなのですが、Javascriptのなさを痛感しました
これから先行きが不安です

# 参考

https://bufferings.hatenablog.com/entry/2021/11/18/015809

https://qiita.com/shiba_it/items/48e92101a31e4a2ba50d

https://stackoverflow.com/questions/45100426/how-to-test-post-calls-in-axios-with-jest-and-axios-mock-adapter
雀魂 コメント欄のプレイヤーのプロフィールを開く

:::note warn
**スクリプトの利用は、自己責任でお願いします。**
:::

雀魂のプロフィールのコメント欄にあるアイコンをクリックすると、コメントしたプレイヤーのプロフィールを開くようにするスクリプトです。開発者ツールで実行できます。

```JavaScript
window.onHeadClick = head => {
    const PlayerInfo = uiscript.UI_OtherPlayerInfo.Inst;
    const comment = PlayerInfo.note.comment_list.find(c => head === c?._cell?.head?.me);
    if (!comment) return;
    PlayerInfo.close();
    setTimeout(() => PlayerInfo.show(comment.commenter.account_id), 700);
};
uiscript.UI_OtherPlayerInfo.Inst.note.content._items
    .map(item => item.container.getChildByName("head"))
    .filter(head => head._mouseEnableState === 0)
    .forEach(head => head.on("click", null, () => onHeadClick(head)));
```
BOOTSELボタンとshell2udpでFlappy Bird【Raspberry Pi Pico W】

![ezgif-4-040bd84c1c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/216a1bb3-8e01-d067-790d-df7ce305867a.gif)

# BOOTSELボタンを押したときにUDPでリクエストを送る

```python:main.py
import gc
import time
import socket
import network

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("aterm-ssid-g", "WIFI_PASSWORD")
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    if rp2.bootsel_button() == 1:
        s.sendto(b"", ("192.168.10.100", 8080))
        gc.collect()
        gc.mem_free()
    time.sleep(0.02)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/53308140-302c-3708-de84-93d3f18f552d.png)

# クリックするだけのサーバーを作る

```bash
sudo apt install xdotool
pip install shell2udp
shell2udp 'xdotool click 1'
```

https://github.com/GitHub30/shell2udp

# Flappy Birdを開いて、BOOTSELボタンを押す

https://flappybird.net/easy-mode/
Reactーadmin

# 8月30日
- GCP上で3000から5000へアクセスできないのは、単に5000側がListenしていなかったから。エラーを治してBackendを動かしたら上手くいった。
- mongooseのSchemaを編集してデータ構造を考えた。
　https://mongoosejs.com/docs/guide.html
- React-admin に日付の表示に仕方　DataFieldを自分で拡張して時刻まで表示できるようにした。
　参考サイト忘れた
```
 import * as React from 'react'
import { DateField } from 'react-admin'

const CustomDateField = ({ ...props }) => {
  return <DateField showTime={true} locales="ja" {...props} />
}
export default CustomDateField
```

- React-adminのUIをデータ構造に合わせて編集した。
AL2内のElastic Beanstalk環境でちょっとした修正を即反映するためにpumaを再起動する方法

# Amazon Linux 1（AL1）

```shell-session
# pkill -f puma
```

# Amazon Linux 2（AL2）

```shell-session
# systemctl restart web.service
```

# ちょっとだけ解説

EB環境でほんのちょっとの修正を何度か試してみたくなること、ありますよね。
でもそのたびに `eb deploy` とかしていると毎度時間がかかってしまいます。
ちょっとした修正をサーバ内でちょちょっとやってしまい、その内容でテストしてみたいのに・・・！
そんな時は `/var/app/current` 以下のソースを編集し、pumaを再起動すれば反映させることができます。

AL1はpumaの起動にUpstartが使われており、単独でpumaを再起動する手立てがありません。（多分・・・）
起動用のUpstartスクリプトは `/etc/init/puma.conf` から `/opt/elasticbeanstalk/support/conf/puma.conf` にシンボリックリンクが張られています。
その中で `respawn` が指定されているため、気兼ねなく`pkill` で `puma` のプロセスをキルすることで再起動させます。

AL2環境に関しては今風（？）の `systemctl` を用いたサービス化がされているのでそのまま `systemctl restart web.service` です。
Serviceファイルは `/etc/systemd/system/web.service` にあります。
laravel php-cs-fixerで自動整形を実行したらエラーが出た

# 概要

- php-cs-fixerで構文チェックを実行したらエラーが出たので解決方法をまとめる。

# エラーまでの経緯

1. 下記の方法を参考に旧ローカル開発環境にてlaravelのアプリケーションにphp-cs-fixerを導入した。
1. 新環境にてコードのクローンとcomposer install（メインとtools/php-cs-fixer直下を指定して実施）
1. 下記コマンドを実行して自動整形を行おうとした。

    ```shell
    ./tools/php-cs-fixer/vendor/bin/php-cs-fixer fix
    ```

# エラー内容

- オリジナル

```
You must call one of in() or append() methods before iterating over a Finder.
```

- 和訳

``
Finder を反復処理する前に、in() または append() メソッドのいずれかを呼び出す必要があります。
``

# 原因

- 本来laravelのアプリケーション構成ファイルにあるはずのphp-cs-fixerの設定ファイル`.php-cs-fixer.dist.php`が新環境になかった。（旧ローカル開発環境でgitignoreで何故か`.php-cs-fixer.dist.php`を設定していた。）

# 参考文献

https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/3830

https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues/1271

https://github.com/FriendsOfPHP/PHP-CS-Fixer/blob/master/doc/installation.rst

https://github.com/FriendsOfPHP/PHP-CS-Fixer

https://qiita.com/miriwo/items/5a7cf3b7858ab1ab146c
KiCad で使用するFreerouting v1.6.2がjava 8で起動しなかった件

# 結論

`Freerouting v1.6.2`では
- JAVA JRE or JDKのversion`17`以上をインストールする

ダウンロードは[ここ⤴︎](https://adoptium.net/temurin/releases/) 

https://adoptium.net/temurin/releases/


# 以下手順

https://github.com/freerouting/freerouting

![スクリーンショット 2022-08-30 17.32.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/39b30c0c-66ed-b0a8-f17e-17640dba6129.png)

↓ここからインストールしたjava8では動かなかった。

https://www.java.com/ja/download/manual.jsp

[freerouting⤴︎](https://github.com/freerouting/freerouting)によると

![スクリーンショット 2022-08-30 17.43.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/89d20e24-c7f9-3cd3-a93a-87fab02a8939.png)

↓以下から `mac`,`使用システムのCPU`,`JRE`,`17`を選択しインストールするようです。

https://adoptium.net/temurin/releases/

![スクリーンショット 2022-08-30 17.48.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/899b11f6-6517-f7c6-0c1c-9fd1843bc07f.png)

あとはインストーラに従って導入してください。
![スクリーンショット 2022-08-30 17.49.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/23fdefef-07ef-ecbb-e05c-b116aa1afa0b.png)

![スクリーンショット 2022-08-30 17.27.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363815/2463da30-26e2-1ba2-d16f-b40460e81bae.png)

インストール後は

```
java -jar freerouting-1.6.2.jar
```

で実行できるようです。
副業エンジニア日記（ざっくり概要編）

# はじめに
紹介文にも書いたが副業を検討しているエンジニアに向けた自分と同じ環境向けの記事を書いていこうと
思う。
このアカウントでの投稿記事の前提条件をつらつら書いてく。

# こんな人の参考になるかも
・エンジニア（ここでいうプログラムの方）で会社員をしながら時間に余裕があると感じる人
・就業時間のコントロールができる職場で時間持て余している
・持て余した時間でプログラミングでお金稼いでみたい。

# 前提条件
・言わずもがな実務経験3年以上系のある人。（基本的には即戦力しか求められていないかと。）
・複数プログラミング言語の経験者（いろんな現場経験しているは強みかも。）

※前提条件こなしていない人は前提条件こなしてからじゃないとお話にならんと思われ。頑張ろう。

# というわけで
筆者は、月1～2万で細々とおこずかい稼ぎできればと思いお仕事を探してみましたが
ピンと来るものがなく、逆にピンと来るものがフリーランス案件の内容の方がピンと来る事が多々あったので
思い切って会社員やりながら個人事業主としてひっそりと活動を開始することに。
もちろんいきなり個人事業主として活動すると決めたわけではなく、順を追っていったらたどり着いた先が個人事業主として
お仕事していく方向だっただけ。

# どんな順で追ったのよ？
・転職の回を重ねた時に自身の職場を変えた時の職場の選び方の考え方が少し変化
↓
・家庭とかを持って将来に対して備えたいと言った時に今の職業や自身の経済状況を良くしたい。
↓
・会社の給料を上げるのはけっこう大変。まずは収支の管理してみる。
↓
・収支の管理や整備してみた。（家計簿とかつけた）会社の給料だけで貯金してみたけど、より稼ぎたいなと思いはじめる。
↓
・副業をやるにはどういうことやる必要があるか調べ始める。とりま一定の金額までは開業届とかそういうのは出さなくても
いいらしい。
↓
・ひとまず手っ取り早く仕事先を見つけたい。ということで転職前の会社にあたってみたら仕事くれて普通に対応できた。
ここで副業をやっていけそうか検討してやっていけそうと判断。
↓
・個人事業主の準備をする。フリーランスの案件サイトでお仕事探し→契約先みつかる。

ざっと、こんな感じ。
このQiitaアカウントも今後のお仕事探しで有効活用できるように育てていく予定。

という訳で初記事はこれにて。
【VSCode】折りたたみの強調表示の色を変更する

## はじめに
VSCodeでコードを折りたたむと折りたたんだ行が以下のように強調表示されます。

![スクリーンショット 2022-08-30 17.34.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/4c033e55-7fda-6757-2295-e6da4ee0720d.png)

この強調表示の色の変更方法について記載します。

## 変更方法
`stting.json`に以下のように追記することで強調表示の色を変更できます。

```~/Library/Application Support/Code/User/settings.json
{
  "workbench.colorCustomizations": {
    "editor.foldBackground": "#ffffff07"
  },
}

```

![スクリーンショット 2022-08-30 17.36.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/7bca5a93-35e6-c12e-79c8-8bda52908448.png)

また強調表示しないようにするには以下を追記します。

```~/Library/Application Support/Code/User/settings.json
{
  "editor.foldingHighlight": false,
}

```
![スクリーンショット 2022-08-30 17.38.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/62cbefa3-cdc7-c20a-8a71-63fb4b7eafc7.png)
消してしまったStashにもう一度会いたい

# 前提
このStash必要なくなっちゃったな~目障りだし消しちゃえ。えい。
??「やっぱ変更！必要でした！」

…大切なものはいつも離れてから気付く。
君はいつも、私のことを支えていてくれたのに。

# 俺が悪かった
帰ってきてくれ。
ターミナルかコンソールを開いて以下のコマンドを実行。
```
    $ git fsck | awk '/dangling commit/ {print $3}' 
```
`fsck`はファイルシステムを検査・修復するコマンドだそうです。
心なしか`dangling`がダーリンに見える。
ダーリンとの関係を修復。あの頃をもう一度。

`dangling commit`はぶら下がったコミットだそうです。。どういうこと？

`awk`はよくわからなかったです。テキストデータを処理するコマンドらしい。
テキストファイルもしくは標準入力からテキストを読み込んで、マッチングを行う。
マッチングが成功した場合には、そのパターンに対応するアクションが実行される。。とのこと。

とりあえずこのコマンドを実行。

# 実行結果
```
Checking object directories: 100% (256/256), done.
Checking objects: 100% (29551/29551), done.
abcdefg12345678902345678901234567890abcd
iedvuibr1345678jnevjx~~~~
・
・
```
このdoneの下の英数字がいなくなったダーリンを表しているようです。
別れた数が多い方ほど表示が多くなるとか。

# 目的のdalingをcherry-pickでとってくる

```
$ git cherry-pick -n -m1 abcdefg12345678902345678901234567890abcd(目的のファイル)
```
上記のコマンドを実行することにより、別れたStashが戻ってきます。
どれかわからない場合はcherry-pickしては確認を繰り返すか、ログを出して確認します。
ログの出し方はまた経験した際に追記します。

cherry pickは英語で、自分の気に入ったものだけをつまみ食いするという意味を持つそうで、
ここでは特定のcommitを現在のブランチにコピーさせるということをしています。

# おかえり
とりあえず戻ってきてよかった。
また仲良くしようね。Stash。
というか、ｳｰｰｰｰﾝ相変わらずLinuxはわかりませんなぁ。
パソコンの中身をいじるとなると、アプリ作成とかと比較して毛色が異なってくるように感じます。
一つ一つ丁寧に見れば理解はできるのですが、なんか難しい。脳が502 Bad GateWay。
おそらく頭頂葉あたりが`sudo rm`されているんだと思います。
こればっかりは`fsck`できないようです。
Raspberry Pi Pico Wの温度センサー【MicroPython】

```python:main.py
import machine
import utime

# 温度センサが接続されている、
# 4つ目の ADC(アナログデジタルコンバータ) を取得します
sensor_temp = machine.ADC(4)
# ADCの最大電圧3.3Vを16bit(65535)で割って、
# 16bitの 1 目盛りのあたりの電圧(変換係数)を計算します( 約 0.00005V)
conversion_factor = 3.3 / (65535)

while True:
    # センサから取得した値(0~65535) を電圧に変換します。
    reading = sensor_temp.read_u16() * conversion_factor
    # 温度を計算します。センサは27度を基準にしているため、
    # 温度センサの数値を27度から引いて計算します。
    temperature = 27 - (reading - 0.706)/0.001721
    print(temperature)
    utime.sleep(2)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/b84f4e13-8d85-3715-5674-304ce0d90058.png)

![ezgif-1-61e2f0cdfd.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/208363/e98c79a4-4a2f-7084-76b4-42504de38c6e.gif)