OmniAICreator/Qiita-1.07M huggingface dataset:
【Swift】Delegateの使用

デリゲートとは、他のオブジェクトがプログラム中のイベントに遭遇したときに、そのオブジェクトに代わって、あるいは協調して行動するオブジェクトのことです。

:::note warn
重要： この記事を投稿したのが2021年12月03日（金）で自身の法人サイトの方でしたけれども、公式サイトの更新などでブログ系のメンテナンスが大変だったので、ここに過去の投稿の移動とこれからの記事を投稿をする予定です。
:::

## 概要
デリゲートは、アプリ内のイベントを通知するCocoaオブジェクトとのやり取りに使用します。

## Delegate Protocolの採用
CocoaのAPIには、デリゲートメソッドを含むプロトコルが用意されていることが多い。ユーザーがウィンドウのサイズを変更するなどのイベントが発生すると、デリゲータであるクラスがそのイベントを検出し、デリゲートとして指定されたクラスのデリゲートメソッドを呼び出します。デリゲートメソッドは、アプリがイベントに反応する方法をカスタマイズすることができます。

以下の例では、NSWindowDelegateプロトコルを採用し、そのwindow(_:willUseFullScreenContentSize:)メソッドを実装しています。

```swift
class MyDelegate: NSObject, NSWindowDelegate {
    func window(_ window: NSWindow, willUseFullScreenContentSize proposedSize: NSSize) -> NSSize {
        return proposedSize
    }
}
```

## デリケートの存在を確認する
Cocoaのデリゲーションパターンでは、デリゲートをインスタンス化する必要はありません。イベントに応答する必要がない場合は、デリゲートを作成する必要はありません。オブジェクトのデリゲートのメソッドを呼び出す前に、デリゲートがnilでないことを確認してください。

以下の例では、NSWindow を作成し、メッセージをデリゲートに送信する前に、ウィンドウのデリゲートが存在するかどうかをチェックするために、オプションのチェイニングを使用しています。

```swift
let myWindow = NSWindow(
    contentRect: NSRect(x: 0, y: 0, width: 5120, height: 2880),
    styleMask: .fullScreen,
    backing: .buffered,
    defer: false
)

myWindow.delegate = MyDelegate()
if let fullScreenSize = myWindow.delegate?.window(myWindow, willUseFullScreenContentSize: mySize) {
    print(NSStringFromSize(fullScreenSize))
}
```

次の投稿では、さらにカスタム・デリケートの作り方の投稿をしたいと思います。
Safariで開いてたタブが消えたとき（Safariで開いてるタブをエクスポートしたいとき）

## Safariのタブって開きっぱなしにしますよね
で、safariのバグか何やらで急に消えることがあります。

ブックマーク取ってなかったりとか、読みかけを残してたりするとモヤモヤします。

### どっかにあるんじゃないか？
iCloudで共有されたりしているので、開いてるタブ情報はどっかに保存されているはず。

で、ググった。

ちょっと前の情報では
`~/Library/Safari/CloudTabs.db`
に入ってるとのこと。
なお、このファイルはsqliteになっているのでコマンドや適当なGUIで開く。

#### だが、なぜかタイムスタンプが古い

そのはず、最近のVer（Monterey）では場所が変わってるみたい。
新しい場所は
`~/Library/Containers/com.apple.Safari/Data/Library/Safari/CloudTabs.db`

ちゃんとあった！！
これで開いてるタブをエクスポートして定期保存したり色々できる！

ちなみにSafariがクラッシュしたときなどはTimemachineからリカバーしたら良し。
paiza.ioでelixir その42

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
Forthインタープリタを書け。
forthで数9を4個つかって1から15までの数を表す式を実行せよ。
Listを使え。

# サンプルコード

```

defmodule Forth do
	def start_link do
		Agent.start_link(fn ->
			[]
		end, name: __MODULE__)
	end
	def add do
		Agent.update(__MODULE__, fn stack ->
		    po = length(stack) - 2
		    top = List.last(stack)
		    stack = List.update_at(stack, po, &(&1 + top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def sub do
		Agent.update(__MODULE__, fn stack ->
		    po = length(stack) - 2
		    top = List.last(stack)
		    stack = List.update_at(stack, po, &(&1 - top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def mul do
		Agent.update(__MODULE__, fn stack ->
		    po = length(stack) - 2
		    top = List.last(stack)
		    stack = List.update_at(stack, po, &(&1 * top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def div do
		Agent.update(__MODULE__, fn stack ->
		    po = length(stack) - 2
		    top = List.last(stack)
		    stack = List.update_at(stack, po, &(&1 / top))
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def dup do
		Agent.update(__MODULE__, fn stack ->
		    top = List.last(stack)
		    stack ++ [top]
		end)
	end
	def drop do
		Agent.update(__MODULE__, fn stack ->
		    po = length(stack) - 2
			stack = List.delete_at(stack, po + 1)
		end)
	end
	def get do
		Agent.get(__MODULE__, fn stack ->
			List.last(stack)
		end)
	end
	def push(n) do
		Agent.update(__MODULE__, fn stack ->
		    {v, _} = Integer.parse(n)
			stack ++ [v]
		end)
	end
end

defmodule Main do
    def run(str) do
    Enum.map(String.split(str, " "), fn s ->
        cond do
	    s == "+" ->
		    Forth.add
	    s == "-" ->
		    Forth.sub
	    s == "*" ->
		    Forth.mul
	    s == "/" ->
		    Forth.div
	    s == "dup" ->
		    Forth.dup
	    s == "drop" ->
		    Forth.drop
	    s == "." ->
		    IO.inspect Forth.get
	    true ->
            Forth.push(s)
        end
    end)
    end
end

Forth.start_link

Main.run("9 9 - 9 9 / .")

Main.run("9 9 / 9 9 / + .")# 2  ok

Main.run("9 9 + 9 + 9 / .")# 3  ok

Main.run("9 9 9 + 9 / dup + .")# 4  ok

Main.run("9 9 9 + 9 / dup + - .")# 5  ok

Main.run("9 dup 9 + 9 + 9 / - .")# 6  ok

Main.run("9 9 9 + 9 / - .")# 7  ok

Main.run("9 9 9 drop 9 / - .")# 8  ok

Main.run("9 9 - 9 * 9 + .")# 9  ok

Main.run("9 9 / 9 dup 9 / + .")# 10  ok

Main.run("9 9 9 + 9 / + .")# 11  ok

Main.run("9 dup 9 9 + + 9 / + .")# 12  ok

Main.run("9 9 9 + 9 / dup + + .")# 13  ok

Main.run("9 dup 9 9 + 9 / dup + - + .")# 14  ok

Main.run("9 dup dup 9 + 9 + 9 / - + .")# 15  ok

```

# 実行結果

```
1.0
2.0
3.0
4.0
5.0
6.0
7.0
8.0
9
10.0
11.0
12.0
13.0
14.0
15.0
```

# 成果物

https://paiza.io/projects/Jd8Jm_76OduaLhs_AptayQ?language=elixir


以上。
自己紹介

この記事は、新たな挑戦への第一歩として、プログラミングを勉強していく上での備忘録として書いていこうと思います。

記念すべき第１号は自己紹介をしていきます。

東京都在住のFujitoraたこぱーてぃです。
苗字はアルファベット、名前はひらがなでやらせてもらってます。歳は20代前半です。

好きなアニメは涼宮ハルヒの憂鬱、攻殻機動隊です。
これだけでたこぱーてぃが厨二病重症患者だということがわかると思います。

好きな音楽はフラワーカンパニーズの深夜高速です。
と言ってもフラワーカンパニーズ時体はそこまで知りません。。

趣味は。。プログラミングになる予定です。

現在職場では、主にPerlを使ったバッチ処理の仕事をしています。
仕事での目標ではテストコードをさらさら書けるようになりたいと思っています。

並行してPythonの勉強もし始めようと思っており、AIに携わる仕事をしていきたいと思っています。

最初はたわいない投稿が続くと思いますが、頑張ってみなさんの役に立てるような情報を共有したいと思いますのでよろしくお願いいたします。
【Git】コミットメッセージテンプレートの設定方法

## テンプレートのファイルを作成

ファイルを作成しテンプレートを記述します。  

ファイル名やパスはどのようなものでも大丈夫です。  

今回は`~/.gitmessage.txt`を作成します。  

```zsh
touch ~/.gitmessage.txt
```

`~/.gitmessage.txt`以下のように記述します。  

```txt
subject line

what happened

[ticket: X]
```

## Gitの設定を変更する

テンプレートファイルを作成したら以下のコマンドを実行してGitの設定を変更します。  

```zsh
git config --global commit.template ~/.gitmessage.txt
```

上記を実行すると`~/.gitconfig`または`~/.config/git/config`に以下が追記されます。  

```conf
[commit]
  template = /Users/user_name/.gitmessage.txt
```

なおリポジトリごとに設定する場合には以下のコマンドを実行します。  

```zsh
git config --local commit.template ~/.gitmessage.txt
```

## `git commit`する

上記の設定をしてから`git commit`すると以下のように`~/.gitmessage.txt`の記述が
`.git/COMMIT_EDITMSG`に表示されます。  

```COMMIT_EDITMSG
subject line

what happened

[ticket: X]
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# On branch main
# Changes to be committed:
#	modified:   sample/sample.txt

```
async/awaitのaの違い～async wait説への反論

## はじめに

[ncaq氏の記事](https://www.ncaq.net/2017/02/10/)を読んで様々なことを学習できました。

asyncが「syncしない」なのにawaitが「waitする」なのは何故か。awaitがasync waitであるという説は正しいのか。async/awaitの語源について学習したことを記事にしました。

## asyncとawaitのa-の違い

asyncはsynchronize（同期）にa-（否定）が付いてasync（同期しない）となります。

awaitはwait（待つ）にa-（否定）が付いて「待たない」となりません。a-（方向）が付いてawait（待つ）となります。

a-（否定）とa-（方向）の違いです。

## a-（否定）は「エイ」と発音する傾向

:::note info
asynchronous	エイスィンクロナス	非同期

Ajax	エイジャックス(Asynchronous JavaScript And XML)

asymmetry	エイスィメトゥリィ	非対称

asexual	エイセクシュアル	他者に性的魅力を感じない

atheism	エイシイズム	無神論

amoral	エイモラル	道徳心がない

apathy	アパシー	無関心

await	アウェイト	待つ
:::

## awaitとwaitの違い

どちらも「待つ」という意味です。

awaitは、waitよりもフォーマルな単語で、ちょっとかしこまった時に使われます[^1]。

## async/awaitの歴史[^2]

:::note warn
2007年、F# はawaitを用いた非同期ワークフローを追加。

2011年、C# はAsync CTPで初めてasync/awaitを搭載。

2012年、Haskell はasync パッケージを作成。

2015年、Python はasync/awaitを追加。

2015年、TypeScript はasync/awaitを追加。

2017年、JavaScript はasync/awaitを追加。

2019年、Rust はasync/awaitを追加。

2020年、C++ はco_return, co_await, co_yieldの新しいキーワードでasync/awaitを追加。

2021年、Swift はasync/awaitを追加。
:::

async/awaitの歴史の中で C# が初登場です。

次に登場するC#での命名者の回答からawait命名の由来を学習できます。

## C#のIssueを読む

ncaq氏が2018年1月7日に[C#の公式レポジトリに投稿した質問](https://github.com/dotnet/csharplang/issues/1237)を読みました。

await命名者の一人が回答していて参考になります。



HaloFour 氏がコメントしました。

> awaitは「asynchronously wait」の略ではないと思います。
>
> awaitという英単語がすでに存在しピッタリと当てはまるからです。



CyrusNajmabad氏がコメントしました。

>  私は命名者の一人です。
>
>  > なぜwaitではなくawaitと名付けられたのでしょうか？
>
>  waitは適切ではありませんでした。waitが同期ブロックを示す多くの先例がありました。
>
>  > 本当にasync + waitなのか？
>
>  そのようにawaitを擁護する人に会ったことがありません。
>
>  1. awaitは「そのことが起きるのを待っている間に他のことをしてもいい」ことを意味します。
>  2. awaitは「Foo() continue with」または「Foo() continue after」が最も一致します。

## await = async wait説への反論

[C#の言語仕様](https://www.microsoft.com/en-us/download/details.aspx?id=7029)の中でawait xの説明としてAsynchronously wait for x to completeと書いてあります。

ですが、ネイティブはawaitのa（ア）はasync（エイスィンク）ではない（アとエイの発音が違う）と思われるようです。

awaitはすでに存在する英単語のawaitに由来します。async + waitがawaitになったのではなく、awaitがたまたま非同期で待つことを意味したようです。

awaitは「そのことが起きるのを待っている間に他のことをしてもいい」のと「プログラム実行の続きを指定する(Foo() continue after)」という説明が最も一致します。

## JavaScriptでは非同期で待つのみ

awaitが非同期で待つという説明は、JavaScriptでは釈然としません。JavaScriptでは同期で待つことが通常考えられないからです。

JavaScriptはイベントループを回してイベントを順番に実行するので、JavaScriptで同期で待ったらJavaScript自体を止めてしまうことになります。あるイベントが待っている間に他のイベントに実行権を渡すことがJavaScriptのプログラミング作法です。

JavaScriptは非同期で待つのみであり、同期で待つことが通常考えられません。

## さいごに

ncaq氏の記事を読んで、async/awaitの語源について学習したことを記事にしました。

皆さんの学習になれば幸いです。

[^1]: [“wait” と “await” の違いとは？ | 日刊英語ライフ](https://kiwi-english.net/45208)

[^2]:[Async/await - Wikipedia](https://en.wikipedia.org/wiki/Async/await)
Blazor WebAssemblyでファイル名を自然順でソート

# はじめに

複数のファイルを連番で管理するときにはプログラムでソートしやすいようにゼロ埋めしたファイル名を利用していました。Blazor WebAssemblyのアプリで複数のファイルをアップロードして処理した際、ファイル名の順番がWindowsと異なっていると言われて確認したところ、Windowsのエクスプローラーではファイル名の並べ替えが自然順になっていました。

https://ja.wikipedia.org/wiki/%E8%87%AA%E7%84%B6%E9%A0%86

# 現状の動作の確認

Blazor WebAssemblyのアプリで複数ファイルを指定するとき、以下のようなコードを書いていました。

```csharp
private void LoadImageFiles(InputFileChangeEventArgs e)
{
    foreach (var file in e.GetMultipleFiles(maxAllowedFiles))
    {
    }
}
```

`e.GetMultipleFiles()`で取得できるファイルの順番はフォルダーで指定されている並べ替えの順が適用されていました。ユーザーがいつも名前で並べ替えをしていればそれでよいのですが、その想定は無理があるので自然順でのソートを適用することにしました。

# ライブラリのインストール

NuGetをさがしてみたところ自然順のソートはいくつかのライブラリが見つかりましたが、ダウンロード数が多くてメンテナンスもされていそうな以下のライブラリをインストールしました。

https://github.com/tompazourek/NaturalSort.Extension

`_Imports.razor`に`NaturalSort.Extension`を追加します。

```csharp:_Imports.razor
@using NaturalSort.Extension
```

# ライブラリの利用

従来のコードでは普通にソートをしていました。

```csharp
foreach (var content in contents.OrderBy(x => x.Key)) {}
```

`OrderBy`の2番目の引数を指定して自然順でのソートができるようになりました。

```csharp
foreach (var content in contents.OrderBy(x => x.Key, StringComparison.OrdinalIgnoreCase.WithNaturalSort())) {}
```

# おわりに

最初は自然順のソートを自分で実装する必要があるかと思っていたのですが、NuGetでよいライブラリが見つかってよかったです。日本語のファイル名を正常に処理できるかなど、まだ検証できていない部分もあるので、引き続き動作確認をしていきたいと思います。
AWSソリューションアーキテクトアソシエイト SAA-C03 合格体験記

# 前提
* AWSの業務経験なし
* ソフトウエアエンジニア歴20年ぐらい

# SAA合格のために購入した物
* AWS 認定資格試験テキスト AWS認定ソリューションアーキテクト アソシエイト
* C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集（6回分390問）
* tech Stock

# 勉強期間
* １ヶ月ほど

# 勉強内容詳細

* 1週間目は、まずは、テキストを買って読んでみた。さらっと読む感じ。問題も解いたほうがいいなぁと思って、udemyの模試を購入。

| 日日| 題材 | 時間 |内容、結果|
|:-:|:-:|:-:|:-:|
| 1日目  | 認定資格試験テキスト  | 2H  | 軽く1周読む。|
| 2日目   |Skill Bulderの模試   |2H   |20問 正解率4割程度 |
| 3日目  | 認定資格試験テキスト  | 2H  | 軽く1周読む。|
| 4日目  | 認定資格試験テキスト  | 2H  | 軽く1周読む。|
| 5日目  | udemy模試①  | 2H  | 65問解く。正解率4割程度|
| 6日目  | udemy模試①  | 2H  | 模試解説読む|
| 7日目  | udemy模試②  | 2H  | 65問解く。正解率4割程度|

* 2週間目、udemyの模試は、1周目は、問題を解くのがキツかったけど、2周目になると少し楽になる。基本は問題を解いて、不正解の解説を読む。
 
| 日日| 題材 | 時間 |内容、結果|
|:-:|:-:|:-:|:-:|
| 8日目  | udemy模試②  | 2H  | 模試解説読む|
| 9日目  | udemy模試②  | 2H  | 模試解説読む|
| 10日目  | udemy模試③  | 2H  | 65問解く。正解率4割程度|
| 11日目  | udemy模試③  | 2H  | 模試解説読む|
| 12日目  | udemy模試④  | 2H  | 65問解く+解説読む。正解率4割程度|
| 13日目  | udemy模試①  | 2H  | 65問解く+解説読む。正解率6-7割程度|
| 14日目  | udemy模試②  | 2H  | 65問解く+解説読む。正解率6-7割程度|

* 3週目、udemyの模試は8割ぐらい合うようになると、これ以上覚えるのはたいへんだと思ったので、tech stockを購入。本当は、2週間でテストを受験するつもりだったけど、無理だった。

| 日日| 題材 | 時間 |内容、結果|
|:-:|:-:|:-:|:-:|
| 15日目  | udemy模試③  | 2H  | 65問解く+解説読む。正解率6-7割程度|
| 16日目  | udemy模試④  | 2H  | 65問解く+解説読む。正解率6-7割程度|
| 17日目  | udemy模試①  | 2H  | 65問解く+解説読む。正解率6-7割程度|
| 18日目  | udemy模試②、③、④  | 8H  | 65問解く+解説読む。正解率7-8割程度|
| 19日目  | udemy模試①  | 2H  | 65問解く+解説読む。正解率8割程度|
| 20日目  | udemy模試②  | 2H  | 65問解く+解説読む。正解率8割程度|
| 21日目  | tech stock  | 2H  | #0-#15 解く+解説読む。|

* 4週目、問題を解く、間違った問題の解説を読むを繰り返す。

| 日日| 題材 | 時間 |内容、結果|
|:-:|:-:|:-:|:-:|
| 22日目  | tech stock  | 2H  | #109-#119 解く+解説読む。|
| 23日目  | tech stock  | 2H  | #120-#129 解く+解説読む。|
| 24日目  | tech stock  | 2H  | #130-#150 解く+解説読む。|
| 25日目  | tech stock,tech stock模試 | 8H  | #150-#165 解く+解説読む。7割ぐらい|
| 26日目  | tech stock模試,skill Builder模試  | 8H  | 解く+解説読む。8割ぐらい|
| 27日目  | tech stock模試+間違った＋お気に入り  | 3H  | 解く+解説読む。8割ぐらい|
| 28日目  | tech stock模試+間違った＋お気に入り  | 3H  | 解く+解説読む。8割ぐらい|

* 5週目、tech stockの合格体験記みたら、8割安定したら、合格するとあったので、31日目に申込み。申込み後に、udemyの模試⑤⑥やったら70%で、焦る。。。。。。

| 日日| 題材 | 時間 |内容、結果|
|:-:|:-:|:-:|:-:|
| 29日目  | tech stock模試+間違った＋お気に入り  | 3H  | 解く+解説読む。8割ぐらい|
| 30日目  | tech stock模試+間違った＋お気に入り  | 3H  | 解く+解説読む。8割ぐらい|
| 31日目  | tech stock模試+間違った＋お気に入り  | 3H  | 解く+解説読む。8割ぐらい|
| 32日目  | tech stock模試+間違った＋お気に入り+udemy模試⑤、⑥  | 8H  | 解く+解説読む。8割ぐらい、udemyは70%|
| 33日目  | 間違った＋お気に入り+udemy模試⑤、⑥、本番| 5H(本番除く)  | 解く+解説読む。9割ぐらい、本番は6割ぐらい|

# 感想

2週間の予定で、始めたけど、１ヶ月かかった。久しぶりの資格の試験で、すごい緊張しました。
【Swift】MintでSwiftFormatを導入する

# はじめに
https://github.com/nicklockwood/SwiftFormat

SwiftFormatを使ってみました。
初めて使ったので導入方法を記録しておきます。

# やりかた
### Mintfile
```:ターミナル
cd プロジェクトフォルダ
```
Mintfileを作成します
```:ターミナル
touch Mintfile
```
Mintfileを開きます
```:ターミナル
open Mintfile
```
MintfileにSwiftFormatを記載します
```:Mintfile
nicklockwood/SwiftFormat
```
SwiftFormatをインストールします
```:ターミナル
mint bootstrap
```
### .swiftformat
```:ターミナル
cd プロジェクトフォルダ
```
.swiftformatを作成します
```:ターミナル
touch .swiftformat
```
.swiftformatを開きます
```:ターミナル
open .swiftformat
```
.swiftformatにルールを設定します
(詳細は[こちら](https://github.com/nicklockwood/SwiftFormat/blob/master/Rules.md)をみてください)
```.swiftformat
--swiftversion 5.7

--commas inline
```

### Run Script
① プロジェクトを選択します
② ターゲットを選択します
③ 「Build Phases」を選択します
④ 「+」を押します
⑤ 「New Run Script Phase」を押します
![スクリーンショット 2022-11-04 20.32.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/1bfd3848-0e44-2989-8d83-48027cd5ec01.png)
追加した「Run Script」にコードを追加します
![スクリーンショット 2022-11-04 20.35.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/e75d3f73-ea82-0967-364b-0bc8ed2a0425.png)
```shell
export PATH=/opt/homebrew/bin:$PATH

if which mint >/dev/null; then
    # SwiftFormat
    xcrun --sdk macosx mint run swiftformat .
else 
    echo 'warning: mint not installed.'
fi
```

### ビルド
ビルドします
![スクリーンショット 2022-11-04 20.37.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/4f7c81a5-d6d3-531e-8196-20fe9c6a6e9a.png)

ビルドが成功するとSwiftFormatに沿ったコーディングルールに変更されます
![スクリーンショット 2022-11-04 20.38.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1745371/083451b1-c500-50fb-a1e4-3fce218fc076.png)

# おわり
SPMが変更されてるのが気になる。。。
AlfredでGoogle Chromeのプロファイルを切り替えたい！

## TL;DR
Chromeのプロファイルを切り替えるAlfredワークフローを作った話。
https://github.com/murakami97/google-chrome-profile
![alfred_chrome_profile.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658770/4e0c9960-cd05-ca19-f547-b8972ab194d3.jpeg)

## 目次
[1. 背景](#1-背景)
[2. 道具](#2-道具)
[3. 実装](#3-実装)
[4. 所感](#4-所感)

## 1. 背景
### Chromeのプロファイル機能
私は以前Safariをメインのブラウザとして使っていたんですが、閲覧権限をGoogleアカウントによって制御しているリソースにアクセスしたいとき、いちいちアカウントを切り替えたり、ログインし直したりする必要があって面倒でした。
Chromeのプロファイル機能を使えばログインアカウントやブックマークの情報を切り分けられるので、作業を始めるときに適切なプロファイルを選択しておくだけで、作業中はアカウント管理を意識しなくて済みます。
私は普段、学校用・職場用・個人用の3つのアカウントを使い分ける必要があって、プロファイル機能にはかなり恩恵を受けています。

### マウスで操作したくない
Chrome以外のアプリを使っている途中で、`A` というプロファイルのChromeウィンドウを開きたくなったとしましょう。このとき必要な操作は次のようになると思います。

1. DockのChromeアイコンか適当なウィンドウをクリックして、Chromeをアクティブにする。
1. 画面右上のメニューバーの `プロファイル` をクリックする。
1. 表示される候補の中から、目的のプロファイル `A` をクリックする。

というわけで、マウスポインタを動かしながら狙ったところを3回クリックする必要があります。どうせ決まった動きしかしないので、ワークフロー化してキーボード入力だけで済ませたいところです。

## 2. 道具

- Alfred
たぶん割とメジャーなMac用ランチャーアプリ。Spotlightみたいにキーボードショートカットで呼び出して、アプリ起動、ファイル検索、ワークフロー実行などいろいろできます。ワークフロー実行は有料版のみの機能なのでご注意。
今回はワークフローを使うので、有料版が必要です。

- AppleScript
MacのGUI操作を自動化したいときに便利です。

- Python
AppleScriptで文字列整形とかしたくないのでPythonでやります。

## 3. 実装
https://github.com/murakami97/google-chrome-profile
![workflow.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2658770/a91c5001-6472-1247-3a32-0ed8cb8b596e.png)

### イメージ
1. Chromeのプロファイル一覧を取得 (AppleScript)
1. Script Filter用のjsonに整形 (Python)
1. 選択されたプロファイルをクリックする (AppleScript)

## 4. 所感
めちゃくちゃちょっとした操作の自動化ですが、ポインタで何回も狙ったところをクリックするのが個人的に結構ストレスだったので、なかなかいい感じです。
コピペで使える！PYTHONとエクセルで13桁unixtime数字羅列をpythonで一瞬で日付型に変換しデータフレームへ格納する

# 13桁unixtimeのtimestamp列を日付が見れるditetimeに変換しデータフレームへ格納します。

インプット前提
　　df['unixtime']　←例えば13桁の数字が入っているとします。ex)1234567890123
最終目的
　　df['datetime']　←2022-12-12 01:01:12　こうなります！%Y-%m-%d %H:%M:%S

# ①日付が13桁なので　2022-12-13  17:52:49　に修正する
```

df['datetime'] = df['updateTime'] / 1000 #13桁の為unixtimeを1000で割ります。
df['datetime'] = pd.to_datetime(df['datetime'].astype(int), unit='s') #13桁から日付へ変換します。
df['datetime'] = df['datetime'] + pd.Timedelta(hours=9)#UTCから日本時間に日付へ変換します。
print(df['datetime'])#一旦出力　日付はUTCの為注意

df['datetime'] = pd.to_datetime(df['datetime'], format="%Y-%m-%d %H:%M:%S")#日付をobject型から日付型に変換します。
print(df["datetime"].dtypes)#Date列はdatetime64型、#Date列の要素はTimestamp型となります。
print(type(df["datetime"][0]))#typeを表示　datetime64[ns]　<class 'pandas._libs.tslibs.timestamps.Timestamp'>
```

# ②　なお現在時刻をサササと取得する方法はこちら


```
# 作成日次と時刻を表示する
import datetime
now = datetime.datetime.now()
date = now.strftime("%Y-%m-%d %H:%M:%S") # 例えば　2022-12-13  17:52:49　のように格納される
```
# ③エクセルの上で13桁の数字がある場合は以下をコピペ

```
=(((M2/1000/60)/60)/24)+DATE(1970,1,1)

その後にセル形式を日付に選択
13桁の場合は1000で割る
```
なぜ3DCGソフトは拡大縮小、回転、平行移動ができるのか？

# はじめに
こんにちは、主にUnrealEngineとBlenderを独学で勉強している大学生です。
記事を書いた方が記憶に残ると思い、はじめてみました。もし間違ってることがあったら教えてください。無断転載にはならないようBlenderの操作(やUnrealEngineの操作)と絡めて差別化します。


※追記)　11/6までの記事は間違いが多数ありました。点の座標と図形の大きさを混同していました。正しい考え方は、図形の大きさが点の座標に紐づいているという考え方です。下にある行列の計算は点の座標の計算です。点の座標が変わることで、それに紐づいている図形の大きさや角度が変化します。



# なぜ3DCGソフトは拡大縮小、回転、平行移動ができるのか？
結論から言います。行列の掛け算と斉次座標（同次座標）系が使われているからです。
まず前半で拡大縮小と回転の仕組みを説明し、後半で平行移動の仕組みについて解説します。（ただし、原点周りの拡大縮小、回転を取り扱うこととする。原点以外は合成変換という処理が入る。詳しくは参考文献の書籍p37）

## 拡大縮小と回転は行列の掛け算で再現されている？
```math              
\begin{pmatrix}
1 & 0 & 0 \\
0 & 1 & 0 \\
0 & 0 & 2 
\end{pmatrix}


\begin{pmatrix}
1 \\
1  \\
1  
\end{pmatrix}

を掛け算すると
\begin{pmatrix}
1 \\
1  \\
2  
\end{pmatrix}となる。
```


これは3DCGではどう表現されているのでしょうか？みなさん2×2×2の立方体を考えてください。
Blenderをやられている方はデフォルトの立方体を選択した状態で GX1→GY1→GZ1 を押して下さい。黄色の点の座標が(1,1,1)になると思います。(黄色の点は立方体の中心にある点のこと)
この状態から上の真ん中にあるターゲットマークみたいなアイコンから3Dカーソルを中心をクリックします。この操作の目的は原点を中心にして立方体の拡大縮小を考えるためです。



### 2×2×2の立方体---黄色の点(1,1,1)
![スクリーンショット 2022-11-07 21.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926688/5e48c6fc-a4b8-fac5-8529-ccf6d6332cc3.png)

次に、立方体を選択した状態で S→Z→2 を押します。
その状態で数字の2を押します。そうすると立方体の高さが2倍になると思います。これの理屈は黄色の点の座標が(1,1,2)になったので、それにひもづいている立方体もZ軸に対して2倍になったためです。


つまり、点(1,1,1)→点(1,1,2)に変化することで2×2×2の立方体から2×2×4の立方体に拡大したと解釈できます。このようにしてオブジェクトの拡大縮小を行っています。



### 2×2×4立方体(Z軸方向に2倍)---黄色の点(1,1,2)
![スクリーンショット 2022-11-07 21.32.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926688/0354237b-4039-a115-1621-33aa397617fd.png)


続いて回転について解説します。
```math              
\begin{pmatrix}
cosπ/3 & -sinπ/3 & 0 \\
sinπ/3 & cosπ/3 & 0 \\
0 & 0 & 1 
\end{pmatrix}
\begin{pmatrix}
1 \\
1  \\
1  
\end{pmatrix}
を掛け算すると
\begin{pmatrix}
-0.365 \\
1.365  \\
1  
\end{pmatrix}

```
この数式は3DCG上では立方体が原点を中心としてπ/3つまり60度反時計回りに回転したことを示します。Blenderで再現してみましょう。

![スクリーンショット 2022-11-07 21.32.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926688/5e48c6fc-a4b8-fac5-8529-ccf6d6332cc3.png)

この状態から上の真ん中にあるターゲットマークみたいなアイコンから3Dカーソルを中心をクリックします。この操作の目的は原点を中心にして立方体を回転させるためです。

次に　R→Z→60　と入力します。
![スクリーンショット 2022-11-07 22.13.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926688/5b9734c2-6327-c9b6-7249-69d0d46ddba0.png)



すると原点を中心として立方体が反時計回りに60度回転したのが分かると思います。よく画像を見てもらうと黄色の点の座標が(-0.365,1.365,1)ぐらいになってると思います。このように行列の掛け算を考えることによって、回転を座標の変換として扱うことができます。






## 平行移動
記事途中書き。(平行移動）

### 参考文献
書籍：[3Dグラフィックスのための数学入門 クォータニオン・スプライン曲線の基礎](https://www.morikita.co.jp/books/mid/009651)
Webサイト：[【Unity】同次座標系をマスターしよう -「w」の正体まで徹底図解！](https://xr-hub.com/archives/12124)
タスク管理ツールをReact + ASP.Coreで作る - Index

長くなってきたので覚書としてIndexを作りました



- コンセプト検討
    - [001コンセプト検討](https://qiita.com/mosuma/items/2c1d07788632b5e3c242)
- 環境設定
    - [002ソリューションと空プロジェクト生成](https://qiita.com/mosuma/items/0afda530de5e8f979a20)：V000-00-00
    - [003サンプルAPIのデータをクライアントサイドで表示する](https://qiita.com/mosuma/items/b6140751f5148efc9e42)：V000-01-00
- タスク一覧画面作成
    - [004一覧リストに表示するデータとDBの検討](https://qiita.com/mosuma/items/ccdce8d079a9f209a675)
    - [005データ型と、ダミーデータを返すAPI作り](https://qiita.com/mosuma/items/246624b5075d92ac528d)
    - [006コードファーストアプローチでDBを構築、初回データ投入](https://qiita.com/mosuma/items/87220f744449f0b07455)
    - [007APIが返すデータをダミーからDBの内容に変更](https://qiita.com/mosuma/items/35703e5e435dda9d8f16)
    - [008Bootstrapで(多少)見やすくする](https://qiita.com/mosuma/items/e0f535ab4406110b6334)
- タスク詳細画面作成
    - [009画面の基本設計とコンポーネント構成検討、空枠作り](https://qiita.com/mosuma/items/58ee9b3012975f7c2495)
    - [010詳細画面構築(操作したいタスクのIDを選択する機能を作る)](https://qiita.com/mosuma/items/e05bb7ac8e8ee80fda42)
    - [011一覧で選択したタスクの詳細情報を詳細画面に表示](https://qiita.com/mosuma/items/0f005e8def0232714185)
    - [012詳細画面に既存タスクの編集機能を追加](https://qiita.com/mosuma/items/07fa83299f70a548fce6)
    - [013詳細画面に新規タスクの登録機能を追加](https://qiita.com/mosuma/items/f3aefbe0adc5dc752d68)
    - [014詳細画面にタスクの削除機能を追加](https://qiita.com/mosuma/items/282e5ca6736cf8291b9c)
    - [015APIとの通信をaxiosを使用してコードを簡略化](https://qiita.com/mosuma/items/75d387607cebdfc22bee)
- 認証機能構築
    - [016サーバーサイドに認証機能関連のクラス追加](https://qiita.com/mosuma/items/728f501bcc7e54352fb8)
    - [017クライアントにユーザー登録・ログイン画面と処理を追加](https://qiita.com/mosuma/items/e606cd33423edfdb4118)
    - [018認証トークン関連機能をサーバー・クライアント双方に追加](https://qiita.com/mosuma/items/035967eb98259bbd4934)
    - [019認証有無に従い制御を実施する機能を追加](https://qiita.com/mosuma/items/82ae859577ab676c06bc)
    - [020認証機能をリファクタリング](https://qiita.com/mosuma/items/82ae859577ab676c06bc)
    - [021認証状態に従って画面表示を制御](https://qiita.com/mosuma/items/5b7ed9431633800e7cc6)
- サイト構成・ルーティング
    - [022ナビゲーションバーを導入](https://qiita.com/mosuma/private/be9f6b343fd7af4d1f6c)
    - [023React Routerを導入して画面遷移やURL指定による操作を可能にする](https://qiita.com/mosuma/items/27d5819e1a4db4d115d6)
    - [024ルーティング見直し・認証状態に応じて自動遷移](https://qiita.com/mosuma/items/deaa1b8b34c9d587ec2c)
    - [025スタイル見直し](https://qiita.com/mosuma/items/283887ac51be58115cab)
    - [026usecontext導入(ユーザー・認証関連情報)]
- 検討中
    - [027スタイル見直し]
    - [028登録・更新・削除時の遷移・そのほかリファクタリング]
    - [029APIとの通信・データ保管をコンテキスト側に持たせる①]
    - [030APIとの通信・データ保管をコンテキスト側に持たせる②]
    - [031存在しないurl・タスクIDを指定した場合にエラー画面に遷移させる]
    - [032各種操作時のメッセージ通知]
    - [033descriptionをマークダウン表示]
    - 完了タスクのアイコンを変更
    - 今は完/未完しかない進捗を細分化
    - カンバンタイプの表示
    - ガントチャートに出来ないか検討
    - ユーザー登録の確認(メール確認)
    - 「プロジェクト」の概念を導入
    - マークダウンをプレビュー
Ruby Threadの非同期処理で処理結果をそれぞれ変数に入れて結果を待ち受ける

```rb
thread1 = Thread.fork { sleep 3; "AAA" }
thread2 = Thread.fork { sleep 6; "BBB" }

thread_return1 = thread1.join.value
p thread_return1 # 3秒程度で表示される

thread_return2 = thread2.join.value
p thread_return2 # 6秒程度で表示される

```

# ここでいうjoinとは

配列のjoinとはニュアンスが違うらしい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/89618/06bf34f2-2da5-1d53-144f-7db5dd53265e.png)

https://docs.ruby-lang.org/ja/latest/class/Thread.html#I_JOIN

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ


# Twitter

https://twitter.com/YumaInaura
Linux Mintにdockerを入れる

基本的には[公式サイト](https://docs.docker.com/engine/install/ubuntu/#install-from-a-package)のUbuntuの説明の通りであるが，ベースとなったUbuntuのディストリビューションを得る方法がUbuntuと異なるのか，以下の部分を変える必要があるようだ．ここだけ詰まった．
```:Ubutnu
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
↓
```:Linux Mint
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release; echo "$UBUNTU_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
```
*webアプリケーション*美術館の評価サイト

## Intro
この前、初めて直島に行きました。
有名な安藤忠雄の地中美術館をも行きました。

この４人の作品しか展示しなかった美術館でした：
クロード・モネ、草間彌生、ジェームズ・タレル、ウォルター・デ・マリア

アートと美術館の建築物を完璧的に融合でき、
最高な美術館でした。

これがきっかけで、美術館の評価サイトを作ってみたいと思いました。
（今はもうたくさんより完成な美術館の評価サイトが存在していますが、
自分の手で作りたいです。）

## codeの紹介
今回の成果物はcodepenを使い、HTML, CSS, Javascriptを使用しました。
そして、このwebアプリケーションは、2つJavaScriptライブラリを使いました：
jquery & vue.js

## code-penのリンク
`https://codepen.io/3luulm/pen/rNKLmGw`

## 作ったwebアプリについての紹介
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885175/5e052fe7-f1b8-d6da-6b8f-9348bc3d0e6e.png)
` https://heroic-cannoli-2d121e.netlify.app`
今回の成果物は2つページがあり、MUSEUMとHOMEです。
MUSEUMは地中美術館の評価ページで、HOMEは他の美術館ページを増やすときのリストまとめです。

自分の発想はCLICK FOR MOREを押すと、美術館の公式サイトに行けます。
下のところでレビュー書きましたら、記録を残ります。

また、元々はBootstrapのnavbarを使いましたが、
codepenのワークは全部分けっていますので、
どうやってhref用のURLを作成するのか解決できませんでした。
そのため、jqueryのライブラリで、こんなふうなタブを作りました。

## 感想
画面を綺麗くねれるために、CSSでの調整は時間かかりました。
そして、タブを作れるためにもgoogleでディスカッションサイトで調べました。
結局は他人のcodepenワークを見つけ、参考した後、自分のwebアプリケーションをできました。
gitの初期設定に関するメモ

pullするときは特に必要ないけどpushするときは必要．
## 名前とメアド
```
git config --global user.name "hoge hoge"
git config --global user.email hoge.hoge@hoge.com
```
GitHubでメールアドレスを非公開にしたい場合はnoreplyメールアドレスを用いる．これはGitHubのsettings->EmailsのPrimary email addressのところに書いてある`${8桁の数字}+${username}@users.noreply.github.com`のことである．
![2022-11-04_07-10-11_region.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2949862/40af3da9-ccc4-51b7-c1f8-7186c5a7a85c.png)

https://github.com/settings/emails

## デフォルトのブランチ名をmainに変更
```
git config --global init.defaultBranch main
```
## Pullしたときの挙動
```
git config --global pull.rebase false
```
これが無難．これで`Warning`が出なくなる．

## .gitconfig
これらの設定をすると`~/.gitconfig`に追加されるので，コマンドを打たずに直接書きこんでも良い．
```
[user]
 name = "hoge hoge"
 email = hoge.hoge@hoge.com
 [init]
 defaultBranch = main                                                                                                         
 [pull]
 rebase = false
```
特定のディレクトリ（例えば`~/Hoge`）の中では別の設定ファイル（例えば`~/.gitconfig-hoge`)を用いたいときは`~/.gitconfig`に以下のように記述する．
```
[includeIf "gitdir:~/Hoge/"]
path = ~/.gitconfig-hoge
```
【Android】PCからWifiでスマホを接続する

# はじめに
今回はPCとスマホの接続をネットワーク（Wifi）経由で接続する方法を調べたので、それを記事にします

# 端末設定
Androidの設定から　システム　→　開発者向けオプション　→ Adb over networkをオンにします
その下に書かれたIPアドレスとポート番号をこの後使用します

９桁の数字がIPアドレス
４桁の5555~5585の番号がポート番号です

IPアドレス:ポート番号というように書かれています
例: 111.111.1.11:5555


また、接続したいPCと端末が同じ回線を使用していることを確認してください

# 接続
ターミナルで
```
$ adb pair 111.111.1.11:5555
```
adb pair の後に　Adb over networkの下に書かれたIPアドレスとポート番号を入力しEnter

```
Enter pairing code: 
adb: No pairing code provided
```
と出てくるのでそのままもう一度Enter

続いて
```
$ adb connect 111.111.1.11:5555
```
と入力しEnter

これで端末とPCの接続ができたはずです！
```
$ adb devices
```
を入力しEnterで接続を確認してみましょう
```
111.111.1.11:5555	unauthorized
```
と　先ほど入力したIPアドレスとポート番号が表示されれば接続成功です！

---
切断時には
```
$ adb disconnect
```
とコマンドを入力することで接続済みのデバイスを切断することができます
Ubuntuを搭載したラズベリーパイへのカメラ認識設定

# 概要
ラズパイとラズパイカメラを使って、映像配信を実施しようとしたところ、ラズパイカメラが認識されなかったので対処法を自分用のメモとしてまとめます。

* 使用環境
    * OS: Ubuntu18.04LTS
    * RaspberryPi4
    * Raspberry Pi カメラモジュール【Raspberry Pi Camera V2】

# 手順
 1. v4l2、v4l-utilsのインストール
    ```
    $ sudo apt install libv4-dev
    $ sudo apt install v4l-utils
    ```
 2.  カメラ有効化の設定 
   ```
    $ sudo vim /boot/firmware/config.txt
   ```

   ```
   # Please DO NOT modify this file; if you need to modify the boot config, the
# "usercfg.txt" file is the place to include user changes. Please refer to
# the README file for a description of the various configuration files on
# the boot partition.

# The unusual ordering below is deliberate; older firmwares (in particular the
# version initially shipped with bionic) don't understand the conditional
# [sections] below and simply ignore them. The Pi4 doesn't boot at all with
# firmwares this old so it's safe to place at the top. Of the Pi2 and Pi3, the
# Pi3 uboot happens to work happily on the Pi2, so it needs to go at the bottom
# to support old firmwares.

[pi4]
kernel=uboot_rpi_4.bin
max_framebuffers=2

[pi2]
kernel=uboot_rpi_2.bin

[pi3]
kernel=uboot_rpi_3.bin

[all]
arm_64bit=1
device_tree_address=0x03000000

# The following settings are "defaults" expected to be overridden by the
# included configuration. The only reason they are included is, again, to
# support old firmwares which don't understand the "include" command.

enable_uart=1
cmdline=nobtcmd.txt

include syscfg.txt
include usercfg.txt
   ```
   上記を[all]のところに```start_x=1```と```gpu_mem=128```を追記する。
3.  v4l-utilsで接続が認識されているカメラ一覧を表示。
/dev/video0が表示されていればカメラ認識に成功している。
```
$ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16

mmal service 16.1 (platform:bcm2835-v4l2):
        /dev/video0
```

以上がUbuntuへのカメラ認識作業です。
以下に参考にさせていただいたページの[リンク](http://m-ac.jp/raspi/hardware/camera/enable_camera/ubuntu/index_j.phtml)を掲載します。
#4 Spring BootでH2 DataBaseを利用する

# #4 Spring BootでH2 DataBaseを利用する
Spring BootでH2 DataBaseを利用して簡単なプログラムを作成する前段階として、この記事では接続設定、テーブル、挿入するデータの作成を行いたいと思います。


# 前提条件
この記事はSpringの最低限の知識が必要になります。
また、なるべく分かりやすく書くつもりですが、この記事の目的は自分の勉強のアウトプットであるため、所々説明は省略します。

# 構築環境
1. バージョン
Spring Boot ver 2.7.5

2. 依存関係
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/33a68c11-81eb-9629-3002-e54230e0b285.png)

:::note
**Spring Boot DevTools：** Webアプリケーションを自動で再起動してくれる
**JDBC API**, **Spring Data JDBC：** JDBCを使用してSQLを実行できる 
**H2 Database：** H2 DataBaseを利用できるようになる
:::


# 今回行うこと
今回は以下の流れに沿って進めていきます。
1. H2 DataBaseとは
1. application.propertiesにH2 DataBaseを利用するための設定を記述
1. テーブル作成のSQLの用意
1. 初期データを投入するSQLの用意

## 1. H2 DataBaseとは
H2 DataBaseはインメモリ型のデータベースであり、全てのデータをメモリ上に持ちます。そのため、Spring Boot起動中のみにしかデータベースを利用することができません。Spring Bootを再起動すると、テーブル、データは消えてしまうため、その仕組みを利用してテストや学習などに利用されている

## 2. application.propertiesにH2 DataBaseを利用するための設定を記述
```properties:application.properties
#DataSource
spring.datasource.url=jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.sql.init.encoding=UTF-8 
spring.datasource.initialize=true 
spring.sql.init.schema-locations=classpath:schema.sql 
spring.sql.init.data-locations=classpath:data.sql 

#H2DB 
spring.h2.console.enabled=true

```

:::note
**DB_CLOSE_DELAY=-1：** H2の接続が切れてもデータベースをドロップしなくなる
**DB_CLOSE_ON_EXIT=FALSE：** VM終了時の自動データベースクローズを無効にする
**spring.datasource.initialize=true：** テーブル作成とデータ投入のSQLを実行する 
**spring.sql.init.schema-locations：** テーブル作成のSQLを実行する
**spring.sql.init.data-locations：** 初期データ投入のSQLを実行する
**classpath：** 「src/main/resources」のこと、schema, data.sqlは「resources」直下に設置
**spring.h2.console.enabled=true：** http://localhost:8080/h2-console にアクセスしてコンソールを利用できる
:::

## 2. テーブル作成のSQLの用意
「src/main/resources」の直下に「shema.sql」を作成
```sql:schema.sql
CREATE TABLE IF NOT EXISTS employee(
	id VARCHAR(50) PRIMARY KEY,
	name VARCHAR(50),
	age INT
	);
```

## 3. 初期データを投入するSQLの用意
「src/main/resources」の直下に「data.sql」を作成
```sql
INSERT INTO employee(id, name, age) VALUES('1', 'Kato', 10)
```
<br>

プログラムを起動して http://localhost:8080/h2-console にアクセスすると、下記の画像が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/0687a872-a980-5782-35d8-d75c93c3ddae.png)

Connectを押すと以下のような画像が表示され、先ほど作成した「Employee」テーブルがあることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/960fc29b-8683-a0ca-9241-9c929872ba1a.png)

テーブルを選択し「SELECT」文を実行すると、今回記述したデータが格納されていることが確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2884987/a6fcb4c4-1f10-980c-beee-45e297d3871c.png)


# 最後に
以上で接続設定を終了します。最後にデータ接続の設定に関して参考にしたサイトがあるので載せておきます。

https://rightcode.co.jp/blog/information-technology/springboot-exercise-record-2-syain

https://zenn.dev/developma/articles/548b9652b01131
デイトラ「Web制作コース」　受講内容をアウトプット 3日目

学んだことをアウトプットしています。完全に自己満足ですので悪しからず。
以下の点を確実にアウトプット
①何で学んでるか
②日々の学習内容
③学びのポイント
④制作物
⑤+αで参考にした記事
⑥+αでやってみたこと

①デイトラ「Web制作コース」
②cssの基本
③新しく学んだことのみ記載（Progateで予習済み）
 ・セレクタ・プロパティ・バリュー
　　h2 { color: red; }
　　　h2…要素を指定（セレクタ）
　　　color…スタイルの種類（プロパティ）
　　　red…プロパティに実行して欲しい具体的な内容（バリュー）

　・直属の子孫要素だけを指定
　　 「>」で繋げることで直属の子孫要素のみを指定可能
　　　例：.contents > p {
 　　　　 　　color: red;
　　　　　　}

  ・font-sizeは、%でも値を指定可能。
　 　pタグはデフォルトで16pxなので200%で32px
　 　例えばh1タグのデフォルトは48px

  ・font-sizeは、emでも値を指定可能。
　 　em=倍の意味、2em=2倍

  ・font-familyはブラウザや環境によって適用できない場合がある。その場合に備えてはカンマを使用して複数指定しておくと良い。

 
　・box-sizingプロパティでborder-boxを指定するとborderまでで指定したwidthとheightの値になる。

　・flexプロパティは画面構成を作成する際にとても役立つ。

④～⑥は特になし
コマンド履歴で補完されなくなった

「何か最近，zshの履歴による補完が出ないような気がするなあ」，「直後とかだったら補完できるけどexitしたりすると消えてるなあ」という事態に陥った．最近設定し直したzshだから何か設定ミスっていたのかと思っていたら，案外単純な原因だった．
```
ls -la | grep .zsh_history
```
結果
```
-rw-------  （中略） .zsh_history
```
権限を`rwx`にしないといけなかった．
```
chmod 700 .zsh_history
```
これで解決．
pysparkのrdd.sortByで、関数の引数で受け取ったカラム名でソートしたい場合の解決法


# 事象
関数の引数で受け取ったカラム名で、rdd.sortByを使って、repartitionする際にソートしつつrepartitionしたいが、strの引数で処理しようとするとエラーが出る

# 環境
python 3.7.4
pyspark 3.1.2

## 例
### 関数例
```python
def hoge(df: pyspark.sql.DataFrame,  partition_num: int, sort_key: str) -> None:
    repartitioned_df = (
        df.rdd.sortBy(lambda r: r[sort_key], numPartitions=partition_num)
        .toDF()
    )
    
    repartitioned_df.write.csv('any_path')
```
### 飛んでくるエラー
```python
df = spark.range(5)
>> df.show()
| id|
|---|
|  0|
|  1|
|  2|
|  3|
|  4|

>> hoge(df, 5, 'id')
_pickle.PicklingError: Could not serialize object: TypeError: can't pickle _thread.RLock objects
```
なんかシリアライズ出来ないっぽい？

# 解決法
受け取ったカラム名のindex(DataFrameを左からの順番)（いい言葉あったら教えて下さい）を、keyfuncで渡すと行ける

## 例
### 関数例
```python
def hoge(df: pyspark.sql.DataFrame,  partition_num: int, sort_key: str) -> None:
    sort_key_index = df.column.index(sort_key)
    repartitioned_df = (
        df.rdd.sortBy(lambda r: r[sort_key_index], numPartitions=partition_num)
        .toDF()
    )
    
    repartitioned_df.write.csv('any_path')
```

### ちなみに
```python
def hoge(df: pyspark.sql.DataFrame,  partition_num: int) -> None:
    repartitioned_df = df.rdd.sortBy(lambda r: r['id'], numPartitions=partition_num).toDF()
    
    repartitioned_df.write.csv('any_path')
```
カラム名をハードコーディングするといけた。
引数がダメっぽい。
Django (>=3.2) で UUID を pk にしたい

現時点 (django = "4.1.3") でのメモ

# 既定のPK指定

[Customizing type of auto-created primary keys](https://docs.djangoproject.com/en/3.2/releases/3.2/#customizing-type-of-auto-created-primary-keys) や [Automatic primary key fields](https://docs.djangoproject.com/en/4.1/topics/db/models/#automatic-primary-key-fields) にある通り、デフォルトのPKを修正するには

- `settings.py` の `DEFAULT_AUTO_FIELD`
```python:settings.py

# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field

DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
```
- `AppConfig.default_auto_field`
```python:apps.py
from django.apps import AppConfig


class HogeConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'hoge'
```

のどちらかを変更すればいいが、これは `AutoField` のサブクラス(4.1実装では `AutoFieldMixin` を実装してるクラス)の

- AutoField
- BigAutoField
- SmallField

以外を指定すると怒られる。

```console
❯ python manage.py migrate
<snip>
ValueError: Primary key 'django.db.models.UUIDField' referred by DEFAULT_AUTO_FIELD must subclass AutoField.
```

https://github.com/django/django/blob/stable/4.1.x/django/db/models/fields/__init__.py#L2752-L2773

```python:django/db/models/fields/__init__.py
class AutoField(AutoFieldMixin, IntegerField, metaclass=AutoFieldMeta):
    def get_internal_type(self):
        return "AutoField"

    def rel_db_type(self, connection):
        return IntegerField().db_type(connection=connection)


class BigAutoField(AutoFieldMixin, BigIntegerField):
    def get_internal_type(self):
        return "BigAutoField"

    def rel_db_type(self, connection):
        return BigIntegerField().db_type(connection=connection)


class SmallAutoField(AutoFieldMixin, SmallIntegerField):
    def get_internal_type(self):
        return "SmallAutoField"

    def rel_db_type(self, connection):
        return SmallIntegerField().db_type(connection=connection)
```

なので、Cloud Spannerなどの要件でPKをUUIDに指定する時は、必ず**各 models に id フィールドとして指定**しなければならない。

# UUIDFieldの型

`models.UUIDField` は、PostgreSQL以外では最長32文字のchar扱い。

https://github.com/django/django/blob/stable/4.1.x/django/db/models/fields/__init__.py#L2612

```python
class UUIDField(Field):
    default_error_messages = {
        "invalid": _("“%(value)s” is not a valid UUID."),
    }
    description = _("Universally unique identifier")
    empty_strings_allowed = False

    def __init__(self, verbose_name=None, **kwargs):
        kwargs["max_length"] = 32
        super().__init__(verbose_name, **kwargs)
```

これはリファレンスにも明記されている。

https://docs.djangoproject.com/ja/4.1/ref/models/fields/#uuidfield

なので、MySQLやMariaDBで扱う場合は36文字じゃ無いことを意識しておくと良い。
UnrealEngine5でPythonの深層学習開発日記

## はじめに

最近，`UnrealEngine5`で`Python`を使った深層学習などをやりたいと思っているのですが，`Unity`みたいにプラグインがまだ充実していない様子です．そこで，その足掛かりとして簡単なプログラムを動かしてみたいと思います．

## 環境

- Unreal Engine 5.0.3
- Windows11


## UnrealEngine5 x Python

### 基礎編
- ☑[【python】UnrealEngine5のEditor Utility Widgetでpythonを使ってみる～Hello world～](https://hamaruki.com/2022/10/29/ue5_python_001/)
- ☑[【python】UnrealEngine5のpythonでpipを使ってみる～Numpyのインストール～【UE5】](https://hamaruki.com/2022/10/29/ue5_python_002/)

### 入出力編
- ☑[【python】UnrealEngine5のPythonでCSVを出力してみる【UE5】](https://hamaruki.com/2022/10/29/ue5_python_003/)
- ✅[【Python】savedフォルダのパスを取得して保存してみる【UE5】(12)](https://hamaruki.com/2022/11/05/ue5_python_012/)
### 自作関数編
- ☑[【python】UnrealEngine5のPythonで自作関数を使ってみた【UE5】](https://hamaruki.com/2022/10/29/ue5_python_005/)
- ☑[【python】UnrealEngine5のPythonで自作関数で引数を返り値を設定してみた【UE5】](https://hamaruki.com/2022/10/29/ue5_python_006/)
- ☑[【python】UnrealEngine5のPythonで今のカレントディレクトリを特定してみる【UE5】](https://hamaruki.com/2022/10/29/ue5_python_004/)
- ☑[【python】UnrealEngine5のPythonでパッケージのパスを特定してみた【UE5】(7)](https://hamaruki.com/2022/11/04/ue5_python_007/)
- ☑[【python】UnrealEngine5のPythonでローカルに自作パッケージを作成してみた【UE5】(8)](https://hamaruki.com/2022/11/04/ue5_python_008/)

### 行動解析編
- ✅[【Python】UnrealEngine5 アクターの行動ログを保存して可視化してみた【UE5】(11)](https://hamaruki.com/2022/11/05/ue5_python_011/)

### 便利編
- ☑[【Blueprint】UnrealEngine5 現在時刻を文字列で取得する関数を作成してみた【UE5】(9)](https://hamaruki.com/2022/11/04/ue5_python_009/)
- ✅[【Python】UnrealEngine5 現在時刻を文字列で取得する関数を作成してみた【UE5】(10)](https://hamaruki.com/2022/11/05/ue5_python_010/)

#ue5
#python
#csv
CompTIA Data+ を取得した

## これはどんな資格なのか。

- アメリカのIT業界団体のデータ分析の資格。
  - 「データドリブン型（データ駆動型）のビジネス意思決定の構築と促進を職務とするデータアナリスト向けのプロフェッショナル認定資格」（Webサイトより引用）

https://www.comptia.jp/certif/dataalytics/comptia_data/


- ~~英語で試験を受けなければならないという点を除けば難易度はそう高くない。~~
  - → 2022年9月より日本語でも試験が受けられるようになりました。

- 計算やロジックについてはほとんど問われないので、そちらの分野で知的好奇心がある方は後述の他の資格の方がお勧め。
  - どちらかというとツールを適切に使える人向けなのかもしれない。
    - 例えばChat-GPTを利用する時にいちいち自然言語による機械学習の事を思い出しながらボタンを押す人は少ない、はず。

## なぜ取ろうと思ったのか。
- 同団体のプロジェクトマネジメントの資格(Project+)を既に取得していた。
  - 同じシリーズでそろえた方が経歴書上、見栄えが良いと思った。 

https://www.comptia.jp/certif/additional_professional/comptia_project/

- グローバル系のデータ分析系の資格を何か一つ経歴書に加えてみたかった。
  - データサイエンス数学ストラテジストも保有しているが、海外でも通用するとは言い難いので。


## 勉強方法
- CompTIA Data+ Study Guide の章末問題をすべて解いた。
（本文を読むのは試験に合格するだけなら不要と判断）

https://www.amazon.co.jp/CompTIA-Data-Study-Guide-DA0-001/dp/1119845254

とはいえ、後述のオンライントレーニングだけで受かるような気がする。

- CertMaster Practice for Data+ Training を全部解いた。

https://www.comptia.org/training/certmaster-practice/data

- CompTIA CertMaster Learn + Labs for Data+, CompTIA CertMaster Learn for Data+ はなくても合格可能と思われる。（取らなかった）

## 結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953203/ec09beac-6621-092c-b7af-f779ebeae6cb.png)

- 合格した。
  - めでたしめでたし。

## 感想
- 英語で受けたこと以外は特に問題となることはないかった。
  - 今は日本語でも受験出来るので、それであればもう少し楽に行けたかもしれない。
  - データシステム（CompTIA DataSys+）、上級データサイエンス（CompTIA DataSci+）なるものが上級編としてリリースが予定されているらしい。[^1]
- とは言え、英文履歴書にも書けるデータ系の資格と言う意味では保有する価値はあると思う。
  - 統計検定、G検定、E資格、データサイエンス数学ストラテジストにしても日本でしか通用しないので。。。


## 追記
- 2025年3月22日追記。本資格に加えてCourseraでGoogleの上級データ分析のコースを履修すると女神転生の悪魔合体よろしく、合体した中二病のような称号を貰えた。正直、これが一番嬉しかった。取得して３年後にご褒美がもらえた感じで非常に満足度が高まった。
  - Google Advanced Data Analytics Certificate & CompTIA Data+ dual credential を取得した #資格 - Qiita https://qiita.com/tatsu_sekine/items/06c0cfc6b5a54428135e

[^1]:https://www.comptia.jp/information/2022/02/comptia-dataplus-newrelease.html
[OutSystems]モバイルアプリケーションをWebアプリケーションのようにブラウザに表示する

[質問箱](https://peing.net/ja/q/3a368835-3441-49a1-a753-dd05f832bc30)で質問もらった内容。質問箱だとスクリーンショットを貼れないのでQiitaにも残しておく。

# 質問内容
モバイルアプリケーションの開発中に、プレビュー画面で選択できる候補以外の解像度で、画面を表示する方法はないか。

プレビュー画面というのは、Service StudioでOpen in Browserを選択したときに出てくる画面。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/a635185f-dc1b-f928-8850-b0f8a49127d5.png)

# 環境
Personal Environment(Version 11.17.0 (Build 36291))
Service Studio(Version 11.53.21)

# プレビュー画面とは
OutSystemsのシステムコンポーネントである、PreviewInDevicesの画面。モバイルアプリケーションのプレビュー（PCのブラウザに端末のプレビューを表示する）画面。

Service Studioでモバイルアプリケーションを開き、Open in Browserのボタンをクリックすると表示される（当然ながらCordovaは動いていないので、Cordova Pluginは使えない）。

画面上部のドロップダウンリストでプレビューする画面サイズをプリセットされたいくつかの候補（iPhone 12 Miniなど機種名）から選択できる。

Service CenterでSite Propertyを見ても候補を追加するUIはないし、システムモジュールなので、Service Studioで編集することもできない。

# 解決策
実はモバイルアプリケーションは、Webアプリケーションと同じURL形式でアクセスすると、Webページとしてブラウザに表示できる（プレビュー機能を使わずに表示できる）。
すると、ブラウザの開発者ツールが備えるDevice Emulateの機能を利用でき、解像度を任意に指定できる。

## ページを開く方法1: URLを直接指定

```
https://ホスト/モジュール名のパス
```
（Webアプリケーションと同じ構造のURL）

## ページを開く方法2: プレビュー画面のアイコンで開く
プレビュー画面上部の右側にあるアイコン（マウスオーバーすると「View in browser」と表示される）をクリックすると、この形式のURLでページを開き直してくれる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/4df99104-07ea-7e60-522d-0b8870a96136.png)

## ブラウザの開発者ツールで端末をエミュレート
Chromeの場合、ページを開いたあとで

1. F12キーで開発者ツールを起動
1. 端末エミュレータを起動（開発者ツール左上にあるスマートフォンとタブレットを重ねた形のアイコンから）
1. アプリケーションを表示するタブの上部にエミュレータの解像度を直接指定するUIが出てくる

端末エミュレータを起動するには以下画像の黄色に塗ったアイコンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/920ac843-e21c-4e15-248e-b33916dbe73d.png)

端末エミュレータの解像度を指定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/332987/251d5f39-01f2-ca4d-ae8e-29dac3466ac1.png)
CompTIA Project+を取得した

## きっかけ
- プロジェクトマネジメントの資格を何か取ろうと考えた。
  - とは言え、私はプログラミング、データサイエンスが主戦場であり、プロジェクトマネジメントの領域で戦うわけではない。
    - 当たり前の話だが開発チーム全員がPM、PLでも困る。
    - 絵に描いた餅にしない為にも実装者は必要。
  - しかし、開発チームを率いるにあたりプロジェクトマネジメントの知識は必要。
- 色々と調べていくうちにCompTIA Project+というPMの資格があることを知る。
  - そのうえで、以下の利点があることに気づき取得を目指した。

## 資格の概要
日本語版はこの辺を参照されたい。

https://www.comptia.org/certifications/project

英語版はこの辺を参照されたい。

https://www.comptia.jp/certif/additional_professional/comptia_project/

## 良かった点
- プロジェクトマネジメントのスキルを客観的に証明出来るようになる。
- プロジェクトマネジメントの知識を体系的に整理できる。
- 世界共通の認定資格なので、海外でも通用する。
  - IPAのプロジェクトマネージャ試験と比較して。
    - IPAも一部の海外の国で相互認証されている[^1]ので、関係先が当該対象国家関連であればIPAでもよかったかもしれない。
- 更新の手間、費用がない。
  - PMPと比較して。
  - もしかしたら、これが一番大きい理由なのかもしれない。プロジェクトマネジメントは技術の分野に比べてそう移り変わりが激しくないので、技術面の向上に安心して集中することが出来る。
- ITSSのキャリアフレームワークと認定試験・資格とのマップ （経済産業省・IPA配下のスキル標準ユーザー協会(特定非営利活動法人)が出している資格難易度表）[^2]によるとPMPと同列に扱ってくれる。
- 米国のIT団体の資格試験にもかかわらず、日本語で受験が可能。
  - 海外に目を向ければプロジェクトマネジメントの資格はPMP以外にも色々あるが、基本英語で受験。[^3]
    - Data+を英語で受験したが、英語の試験を受けるのと、英語で試験を受けるのはまた違う難しさがある。
    - 円安で受験が高くなっているので、プライドを捨てて受かることを最優先。
- 日本での知名度は別にして、世界で通用しそうなのは国連推奨のPRINCE2など。 
  - 結局、どこまでプロジェクトマネジメントに対して熱量をかけられるかの問題かもしれない。

## 良くなかった点
- 知名度がない。
  - やはり、IPAのプロジェクトマネージャ試験、PMPに比べると知名度がない。
  - 故に、価値を理解してもらう事が難しい、場合がある。
- ITSSのキャリアフレームワークと認定試験・資格とのマップ （経済産業省・IPA配下のスキル標準ユーザー協会(特定非営利活動法人)が出している資格難易度表）[^2]によるとスキルレベルはPMPと同列だが、海外のサイトなどを確認するとやはり、PMP > CompTIA Project+。[^4]


## 勉強方法

まず、テキストを通読。

https://www.amazon.co.jp/Project-%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88-PK0-004%E7%89%88-%E5%AE%9F%E5%8B%99%E3%81%A7%E5%BD%B9%E7%AB%8B%E3%81%A4IT%E8%B3%87%E6%A0%BCCompTIA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-IT%E8%AC%9B%E5%BA%A7/dp/4813282350/

次に問題集を２度ほど解いた。（１度通しで解き、間違えた問題のみを再度解いた）

https://www.amazon.co.jp/Project-%E5%95%8F%E9%A1%8C%E9%9B%86-PK0-004%E7%89%88-%E5%AE%9F%E5%8B%99%E3%81%A7%E5%BD%B9%E7%AB%8B%E3%81%A4IT%E8%B3%87%E6%A0%BCCompTIA%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-IT%E8%AC%9B%E5%BA%A7/dp/4813282369/

TACからチケット付きのWeb模擬試験があるので（Project+（PK0-004）Web模擬試験（リテイクチケット付））、Webで模擬試験を実施。
こちらも１度通しで解き、間違えた問題のみを再度解いた。

https://www.tac-school.co.jp/kouza_it/it_crs_comptia_projectplus.html

それ以外にも応用情報技術者試験のプロジェクトマネジメントの範囲を見ておいて損はないと思う。（午前も午後も）

## 結果
- 無事に合格した。
  - よかったよかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2953203/6670b785-bd53-26ef-7b56-cf162df0e77b.png)

## 追記
- 2025年3月追記。Google Project Management Certificateの履修を完了すると追加で称号を貰えました。
  - Google Project Management Certificate & CompTIA Project+ dual credential を取得した #資格 - Qiita https://qiita.com/tatsu_sekine/items/cf9b3d0ece8cde385b37


[^1]: 情報処理技術者試験の海外との相互認証について  : https://www.ipa.go.jp/jinzai/asia/kaigai/001.html

[^2]: ITSSのキャリアフレームワークと認定試験・資格とのマップ :  https://www.ssug.jp/qualification/

[^3]: Top 13 project management certifications | CIO : https://www.cio.com/article/230398/top-project-management-certifications.html

[^4]: IPAのプロジェクトマネージャ試験 > PMPとしたいがために、PMPを3にした結果、CompTIA Project+と同列になってしまったのではないか。なお、CompTIA Project+は難易度的に2ではない気がする。（問題自体の難易度は高くないが、900点中710点以上が合格なので、高い正答率が求められる）
【PHPUnit】ReflectionClassで参照渡しのメソッドを実行

## 実行環境
 - PHP8

## 内容
PHPUnitでprivateやprotectedのメソッドをテストしたい時に、ReflectionClassクラスを使って実行する。
この時に、実行するメソッドの引数が参照渡しになっている場合、エラーになってしまったので解決方法をメモしておきます。

## 失敗例

```php
<?php

class Hello {
    private function sayWord(&$word) {
        echo $word;
    }
}

$param = 'Hello';

$object = new Hello();

$reflectionMethod = new ReflectionMethod($object, 'sayWord');

$reflectionMethod->setAccessible(true);

$reflectionMethod->invokeArgs($object, [$param]);
```

### 実行結果
Warningエラーが発生する。

```
Warning: Hello::sayWord(): Argument #1 ($word) must be passed by reference, value given in test.php 17
Hello
```

## 解決方法
呼び出す際に、引数にも「`&`」をつける必要がある。

```php
$reflectionMethod->invokeArgs($object, [&$param]);
```

### 実行結果
Warningが解消されて実行される。

```
Hello
```
【Laravel 9 アップグレード】パスワードバリデーションが変更

Laravelのアップグレードをしたところ、Laravelさんが提供してくれるパスワードバリデーションが地味に変更されてました。
パスワードバリデーションは、パスワード変更機能なんかで使用されることがあるかと思います。
現在のパスワードと入力されたパスワードが一致しているかを判定してくれるバリデーションです。

Laravelバージョン8までは以下で良かったのですが、
```php
'current_password' => 'password:web'
```
Laravelバージョン9にアップグレードしたことでこちらに変更されました。
```php
'current_password' => 'current_password:web'
```
確かにcurrentついた方がわかりやすいですね。
Add Camera to HomeKit via Homebridge plugin "Homebridge Camera FFmpeg" on Synology NAS

# 1, Confirm you camera rtsp stream.
The url like: rtsp://username:password@ip:port, confirm it by VLC etc.
eg, TpLink camera: rtsp://admin:admin@192.168.00.00:554/stream1

# 2, Install Homebridge APP to Synology NAS.
https://github.com/oznu/homebridge-syno-spk

# 3, Install "Homebridge Camera FFmpeg" plugin in Homebridge APP.

# 4, Set your camera in "Homebridge Camera FFmpeg" plugin.
Video Source: -i rtsp://admin:admin@192.168.00.00:554/stream1
(-i rtsp://admin:admin@192.168.00.00:554/stream2)

# Other
## Unrecognized option 'srtp_out_suite' error
The reason is the plugin is using the old version ffmpeg. You can change the ffmpeg setting in **Global Advanced > Video Processor**.

## How to install another ffmpeg
It is not recomended to upgrade the NAS default ffmpeg at command line, you can add some package source which is contains ffmpeg package, and then install it in your package center.
The new ffmpeg binary file path is `/volume1/@appstore/ffmpeg/bin/ffmpeg`. You can just add the path to plugin "Video Processor" setting.
Of course you can download ffmpeg at NAS command line and then set the "Video Processor" point to it.

https://github.com/Sunoo/homebridge-camera-ffmpeg/issues/1238#issuecomment-1006788079
railsを5000ポートで起動してブラウザで7000ポートでアクセスできるようにする

# 目的
dockerを使っていて、ポートの理解の理解が足りておらず接続エラーになったのでメモ。

Docker Documentation: https://docs.docker.com/compose/compose-file/compose-file-v3/#ports
をみていて、hostのポートとコンテナのポートについて理解したことを書いた。

# docker-compose

ポートマッピングするにはdocker-composeに以下のように書く。

```docker-compose
web:
  ports:
    - "3000:3000"
```
いくつか書き方があるが、上記の書き方はDocker Documentationの

>Specify both ports (HOST:CONTAINER)

に従っている。ここの意味は「コンテナはポート番号3000で起動していて、ホストのサーバーはポート番号3000で起動していますよ」ということ。どちらも3000なのでわかりづらいが、

もし```- "3001:3000"```とした場合「コンテナはポート番号3000で起動していて、ホストのサーバーはポート番号3001で起動しています、ということ。この書き方の場合hostのIPアドレスは省略されており```0.0.0.0```が指定されている。```0.0.0.0```はローカル上のすべてのIPv4アドレスのこと。実行すると「自ホスト宛の通信はIPアドレス関係なくポート番号3001で受け入れて、コンテナのポート番号3000番に転送する」という結果になる。




# 結論

まとめると題名の通り「railsを5000ポートで起動してブラウザで7000ポートでアクセスできるようにする」には下記のように記述すれば実行できる。

```docker-compose
web:
  ports:
    - "7000:5000"
```