OmniAICreator/Qiita-1.07M huggingface dataset:
docker-composeで管理しているrailsアプリケーションのGitlab-CIテストが走らない

## GitlabのCIが動かない！
バイト先でdockerを使ってrailsアプリケーションを管理していましたが，
自動テストをするために以下のサイトを参照してGitlab-CIの設定をしました．
https://www.insight-tec.com/tech-blog/20201222_gitlab_runner/

一通りの設定をして動いたので喜んでいたのもつかの間
気が付いたらこんなエラーが発生していた．

```
Reinitialized existing Git repository in /home/gitlab-runner/builds/*****/0/*****/*****/.git
Checking out 0cff3126 as master...
warning: failed to remove tmp/***: 許可がありません
```

ざっくりまとめると，
テストをするためにローカルにデプロイしたいから不要なファイルを削除しようとしたら
許可が無くて削除できないよ！
って感じでした．

## なぜこのようなことが起きたか
調査の過程などを省いて結論に飛びますが，
docker-composeを動かす上で，コンテナ内で処理をする際にroot権限で処理されるように設定していました．
その結果，dockerコンテナ内で作成されたファイルやフォルダには管理者権限が付与されるようになっていました．
そのため1回目のテストでは問題なく動きますが，2回目以降では1回目でコンテナ内で作成されたファイルが，
権限の問題で操作ができなくなってしまったと考えています．

## 解決方法
権限の問題なので方法に関してはいくらでもあると思います．

やり方としては、

- CIの最後に特定のファイルを削除する処理を追加  
- CIをrootユーザーで実行,または管理者権限のあるユーザーで実行
- テスト毎に権限の書き換えを事項

今回は３つ目の方法を行いました．
具体的な方法としては
gitlab-runnerにCIを登録する際に，``--pre-clone-script``を追加する方法です．

```
 sudo gitlab-runner register -n --executor shell --tag-list "blog-sandbox" --url https://gitlab.com/ --registration-token $GITLAB_SPECIFIC_RUNNER_TOKEN --description "shell executor for sandbox"  --pre-clone-script "sudo chown -R gitlab-runner:gitlab-runner ."
```

これによってクローンの前に権限の書き換えを行うようになります．

またこのままだと管理者の書き換えの際にパスワードを求められたりするので，ユーザーの権限を変更します．
以下のコマンドで``/etc/sudoers``を開きます．

```sudo visudo```

そして最後の行に以下の一文を書き加えます．

```
gitlab-runner ALL=(ALL) NOPASSWD:ALL
```

これによりgilab-runnerのユーザーがsudoを実行してもパスワードを求められることがなくなり，
CIが動くようになりました．
[競プロ] MaxとMinを取得できる自作Map

leetcodeの2034. Stock Price Fluctuationを解くために必要なデータ構造の解説

https://leetcode.com/problems/stock-price-fluctuation/

# 概要
下記の3種類のオペレーションを高速化する問題

1. keyで指定された値を更新。存在しない場合は新規作成
2. 最大値を取得
3. 最小値を取得

1の更新がなければpriority_queueを使うことが可能。
2,3がなければ単純なMap
セグメント木やフェニック木ではオーバースペック。またKeyの範囲が広いと使用メモリが多すぎる。
なので、最大値と最小値を取得できるMapを自作する。

# 方針

ベースにはMapを使ってkeyと値を管理する。
最大値と最小値を取得するために、今Mapに入っている値を別のMapを使ってソート状態で管理する。
更新のたびに更新前の値をソートMapから削除、更新後の値を追加する。

# 実装

```c++
class MinMaxMap {
private:
    unordered_map<int, int> mp;
    map<int, int> ordered;

public:
    void update(int key, int value) {
        if (mp.count(key) > 0) {
            int prev = mp[key];
            ordered[prev]--;
            if (ordered[prev] == 0) ordered.erase(prev);
        }
        mp[key] = value;
        ordered[value]++;
    }
    
    int maximum() {
        return ordered.rbegin()->first;
    }
    
    int minimum() {
        return ordered.begin()->first;
    }
};
```
早期リターン（ガード節）の書き方メモ

勉強したはずなのに早期リターンの書き方の方がいいよと指摘されたときにそれなんだっけってなったので（やばい）思い出しがてらメモです。リーダブルコードにも書いてあって勉強した気がしますが記憶が抹消されていました。


#早期リターン（ガード節）とは
メソッドなどで処理の終端に到達する前に、条件を満たしたときにはすぐにreturn や continue/break で抜ける方法です。

#書き方
`age`データがある場合に年齢を判断して乳幼児、未成年、成人を返す関数があるとします。

```.js
function checkAge(age) {
    let result;
    if (age != null) {
         if (age == 0) {
             result = "乳幼児"
          } else if (age < 20) {
            result = "未成年"
          } 
          else if (age >= 20) {
            result = "成人以上"
          }
     } else {
        result = "年齢情報なし"
     }  
     return result
}
```

正常系コードがネストの深い位置にあります。今回は簡単な例ですが、処理がもっとあった場合など、他の人が処理を追う時にパッとはわかりづらい。。。

　
早期リターンの書き方で書いてみましょう。

```.js
function checkAge(age) {
    if (age == null) { 
        return "年齢情報なし"
    }
    if (age == 0) { 
        return "乳幼児"
    }
    if (age < 20) { 
        return "未成年" 
    }
    if (age >= 20) { 
        return "成人以上"
    }
}

```
スッキリかけました。どの場合になにを返すのかわかりやすいです。
また、nullの判定を最初に持ってきています。もっと細かい処理があったとしてもnullの場合は後述の判定をすることなくすぐに抜けることができるので余計なコードを読み込まなくなります。
Goのsortパッケージでよく使う関数

## はじめに
Go標準のsortパッケージでは、スライスの並び替えなどをサポートしています。
本記事では、sortパッケージで一般的に利用される関数を紹介していきます。  

## Ints
int型のスライスを昇順で並び替えます。

```go:go
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []int{5, 2, 3, 1, 4}
	sort.Ints(s)
	fmt.Println(s) //=> [1 2 3 4 5]
}
```
一般的なソート（バブルソート）と比較してみます。

```go:go
package main

import "fmt"

func main() {
	s := []int{5, 2, 3, 1, 4}
	for i := 0; i < len(s)-1; i++ {
		for j := 0; j < len(s)-1-i; j++ {
			if s[j] > s[j+1] {
				s[j], s[j+1] = s[j+1], s[j]
			}
		}
	}
	fmt.Println(s) //=> [1 2 3 4 5]
}
```
Intsを使うだけでも、かなりのコード量を削減できますね。
## Strings
string型のスライスを昇順で並び替えます。

```go:go
package main

import (
	"fmt"
	"sort"
)

func main() {
	s := []string{"A", "C", "ab", "aa", "B"}
	sort.Strings(s)
	fmt.Println(s) //=> [A B C aa ab]
}
```
## Slice
第2引数で渡した関数の処理を条件として、スライスを並び替えます。
若干ややこしいので、コードも交えて説明します。

```go:go
package main

import (
	"fmt"
	"sort"
)

func main() {
	people := []struct {
		Name string
		Age  int
	}{
		{"Gopher", 7},
		{"Alice", 55},
		{"Vera", 24},
		{"Bob", 75},
	}
	sort.Slice(people, func(i, j int) bool { return people[i].Name < people[j].Name })
	fmt.Println(people) //=> [{Alice 55} {Bob 75} {Gopher 7} {Vera 24}]
}
```
第2引数で渡した関数内で、for文が2重で実行されていると考えてください。
`people[i].Name`と`people[j].Name`を比較し、小さい要素を前に持ってくるイメージです。
Ageで並び替えたい場合は、Nameの箇所をAgeに変更してください。

## まとめ
アウトプット感覚で書きましたが、ご満足いただけたら幸いです。
Goを触り初めて1週間のド素人ですので、間違いなどがありましたら指摘していただけると助かります。

## 参考
https://pkg.go.dev/sort?utm_source=gopls#example-Slice
Angularの環境構築

#そもそもAngularとは
Angularはモバイルおよびデスクトップ環境両方に対応したwebアプリケーションを作成するためのプラットフォームです。
Angularの導入をするだけで、開発ライブラリとデバッグ用のツールが準備できます。
[公式サイト](https://angular.jp/guide/what-is-angular)によると以下のような利点があるようです。

* 個人開発もエンタープライズレベルの開発もOK
* コンポーネントという単位でアプリを組み立てることができ、最小限の労力で開発ができる
* 170万人を超える多様なグループによるエコシステムで、もっと安定化＆もっと便利に

#環境準備
操作は基本的にはターミナルやコマンドプロンプトなどで行います。
筆者はWindowsユーザーなのでコマンドプロンプトで操作をしています。

###Node.js&npmの準備
Angularがベースとして使用している、Node.jsのインストールを行います。
以下のページからインストーラをダウンロードして実行します。
このインストーラーでNode.jsのほかにパッケージ管理ソフトのnpmも同時にインストールされます。
[ダウンロードページ（公式サイト）](https://nodejs.org/ja/)

インストールが行われたか確認するためにバージョン確認を行います。
npm -vでnpmの、
node -vでNode.jsのバージョンが確認できます。

###Angularの準備
Angularのインストールはnpmを通じて行います。

```:Angularのインストールコマンド
npm install @angular/cli -g
```

末尾の-gは全ユーザーにインストールさせるオプションです。
既にAngularが入っていて更新したい場合は以下のコマンドを使います。

```:Angularのアップデートコマンド
npm upgrade @angular/cli -g
```

インストールが行われたか確認するためにバージョン確認を行います。
npm list --depth=0 -g
でインストール済みパッケージ一覧が表示され、バージョンの確認ができます。

#Angularプロジェクトの作成と起動確認
Angularのプログラムを作るにはターミナルからコマンドを実行する必要があります。
プロジェクトを作成したいディレクトリにcdコマンドで移動し、
その後、以下のコマンドを実行します。

```:Angularのプロジェクト作成コマンド
ng new 作成したいプロジェクトの名前
```

コマンドを実行すると「Would you like to add Angular routing?　y/N」と聞かれます。
routing機能でページ切り替えを行うので、基本的にはyを選びます（yと打ってEnterで回答）。
次に「Which stylesheet format would you like to use?」と聞かれます。
スタイルシートの種類を選びます。カーソルキーで選択してEnterで回答します。
その後、カレントディレクトリ直下に新しくディレクトリが作られ基本的なファイルが作られます。

プロジェクト作成処理がおわったら、プロジェクトフォルダにcdコマンドで移動し、
以下のコマンドを打ってサーバーを起動します。
このコマンドの実行中は使用中のＰＣがサーバーとなります。

```:サーバー起動コマンド
ng serve --open
```
アプリのコンパイルが終わった後、
自動でブラウザが起動してhttp://localhost:4200/ のアドレスが開かれるはずです（--openオプションの効果）。
画面の表示は以下のようになっています。
![angular_initial_screen.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2049468/ebaff76a-c1ba-ad4f-2444-391f18c6dbaf.png)

ここまで出来たら準備完了です。

サーバーを止めるときは、
ターミナルでCtrl＋Cを押して終了します。
Remote-SSH使用時のダウンロード/アップロード

こちらのツィートで、[Visual Studio Code Remote Development](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack)（というか、[Visual Studio Code Remote - SSH](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-ssh)）だけで、ファイルをリモートサーバーへアップロード、リモートサーバーからダウンロードできる！ということで、雰囲気分かる動作をアップしておきます。

https://twitter.com/mgo_tec/status/1446788672058056708

> Remote Delopment is 何？という方は、こちらをご参照ください。
> [VSCode + Remote - SSHでRaspberry Pi開発](https://matsujirushi.hatenablog.jp/entry/2019/09/08/211119)
> [VS Code Remote Development、3種の違い](https://matsujirushi.hatenablog.jp/entry/2020/12/31/171028)

# ローカルPCからリモートサーバーへ（アップロード）

ファイルを、Visual Studio Codeのエクスポーラーにあるフォルダへドラッグ&ドロップします。

下記動画は、workフォルダにあるtestファイルをアップロードしている様子です。

![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/1e1e4bbf-b3c4-7def-105f-bf37d89a0476.gif)

# リモートサーバーからローカルPCへ（ダウンロード）

Visual Studio Codeのエクスプローラーにあるファイルを右クリックして、コンテキストメニューのダウンロードを選択します。

下記動画は、リモートサーバーにある.profileファイルをダウンロードしている様子です。

![名称未設定.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/109634/45103525-6b84-e33d-7751-d12bc1e65812.gif)
初めてプログラミングを学んだ話

##初めてプログラミングを学んだ話

何事も初学者は学ぶことが多く、とかく挫折しやすい。
プログラミングも例外でなく、むしろ挫折しやすい分野だと思う。

以下の記事によると挫折した人の割合はプログラミング学習の経験者240名で**87.5%**もおり、始めたほとんどの人が挫折しているようだ。

https://prtimes.jp/main/html/rd/p/000000003.000047683.html

また、その理由は、**わからないことを解決できない**、**目的がなくモチベーションが続かないこと**が多いらしい。そもそも**始め方もわからない人**が最も多いと思うので、挫折すらしていない人も数多くいるだろう。

##プログラミング初心者のときの話
###初めてプログラミングをするとき

社会人のプログラミングをする動機は大体が**スキルを身につけたい**や**転職のため**など、**キャリアアップ**を目的としたものが多い。学生であれば、授業や研究で必要となり勉強することもあるだろう。

私は大学院の研究で初めて**Python**を触れ、OSは**Vine Linux**で後に**Ubuntu**の**Terminal**を用いた開発環境だった。プログラムの知識は全くなく、PCの知識もない本当の未経験者だったので、分からないことだらけでプログラムを作るのはとても辛かった。ただ研究という**明確な目的がありモチベーションを保てた**こと、および**指導教官や先輩に質問出来る環境**があったのは、未経験者にとってとても恵まれた環境だったと思う。それがなければプログラミングはやってなかっただろう。

https://vinelinux.org/

https://www.ubuntulinux.jp/home

###始めてから～３か月後
始めの3ヶ月くらいはとても辛かった。パソコンの仕組みも理解してない状況で、いきなりプログラミングするのは色々理解が追い付かず、時間と労力がかかった。やっていたのはシェルスクリプトとインタープリター言語のみだったが辛かった。

3ヶ月くらい経つと、基本的な使い方はマスターして**簡単なやりたいことは、webで調べてコピー&ペーストで自分で作れる**ようになった。ただ、プログラミング処理の理解や、ハードウェアやソフトウェア、ミドルウェアやネットワークの理解は全くなかったので、black boxで使っているような状態だった。そのため、エラーを解決できず自分のできる範囲内で物事を進めることしかできなかった。

###３ヶ月〜３年後
その後はソフトウェア・ハードウェア両面で色々経験や勉強することで、総合的な知識をつけていった。QiitaやStack Overflowなどの技術ブログを読むことで新しいPython moduleを学んだり、C++を教えてもらってコンパイル言語にも触れた。LinuxではなくWindowsでのプログラミングの仕方も会社で学んだ。自作PCはパソコンの仕組みの理解に役立ち、メモリ開放やコンパイル処理の理解に役立った。会社のDNS/Proxyサーバーやデータサーバーの理解は、セキュリティやサーバーについての一部理解につながった。ラズパイによる電子工作は電子機器の動作理解につながった。**様々な経験をすることで総合的に知識が付き、新しいプログラミングについての物事の理解がより容易になり、成長スピードも上がった。**


##まとめ
初めてプログラミングを学んで理解できずつらいこともあると思います。そんなときはモチベーションを保てるものを見つけ、わからないことを聞ける人をみつけると、自分で学んでいけるレベルまできっと頑張れると思います。
RailsアプリでTwitter認証実装中にルーティングエラーになった時の解決法

色々な記事を見ながらRailsアプリにomniauth-twitterを使用してTwitter認証を実装していたのですが、どういうわけかかなりハマりました。
最終的にうまく行ったのでその方法を備忘録がてら記載しておきます。

## 前提
### 諸々のバージョン
使用しているPC: MacBook Air (M1, 2020)
Railsバージョン: 6.1.4.1
Rubyバージョン: ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [arm64-darwin20]
omniauthバージョン: 2.0.4
deviseは使用していません。

### 最終的に参考にした記事
https://qiita.com/d0ne1s/items/7a96b835280f55bb5234

https://takagi.blog/csrf-vulnerability-in-omniauth-twitter-request-phase/

##ハマったこと
omniauth-twitterを使用して認証を実装後、/auth/twitterにアクセスするとルーティングエラーになる

##原因
（おそらく）omniauthバージョンが2以上なのにそれ用の対策をしていなかったこと

##最終的にこうしたらローカルでもうまくいった
基本的な部分は参考の1番目の記事の通りに実装していますので省略します。
そこに以下を追加で実装しました。（詳細は参考の二番目の記事をご参照ください）
1.Gemfileにomniauth-rails_csrf_protectionを追加する

```
gem 'omniauth-rails_csrf_protection'
gem 'omniauth-twitter'
```

2./auth/twitterにはPOSTでアクセスする

```xxx.html.erb
<%= link_to '/auth/twitter', method: :post do %>認証<% end %>
```

おかしな点ありましたらコメント等で指摘いただけると幸いです。
【Flutter】Firebase StorageのUrlDownloadのスピードを半分にする

こんにちわ、語学学習マッチングアプリ『CROSSER』の開発者です。:smile:
この『CROSSER』なのですが、FlutterとFirebaseを用いて開発しております。
今回はFirebase StorageのUrlDownloadのスピードを半分に改善した方法を記載します:fist::fist::sparkles:


#概要
Firebase StorageのUrlDownloadのスピードを早くする方法は他の記事にもありましたが、どれも「Firebase Storageにアップロードした画像を一般公開にする」の方法でした。
しかし、『CROSSER』では一般公開してはまずい画像データを保存していたため、この方法が現実的ではありませんでした。ここでは、一般公開せずに画像のUrlDowonloadのスピードを改善する方法を記載していきます:relieved::star:
ちなみにここで記載するやり方よりも一般公開した方が断然、スピードが早いです!
なので、一般公開しても大丈夫だよ~って場合はこちらの記事を参考になります:thumbsup_tone1:

https://qiita.com/qrusadorz/items/4a8e62c20bc788ab0585

https://qiita.com/teramotodaiki/items/fa3d9b219f3021114383


#どうやってスピードを改善したか？
Firebase Storageでリージョン毎にバケットを作成しました。
たったこれだけでスピードが半分になりました！
今まで画像3枚で30秒くらい(リージョンはUS-central)かかっていましたが、今では7~12秒に改善されました:relaxed:


#リージョン毎のバケット作成方法
Firebase -> Storage -> バケットを追加

![スクリーンショット 2021-10-10 午後8.33.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1642184/ee46fe5c-e287-2176-26f4-2e1cab2af2ac.png)


#バケットの振り分け
日本ユーザーだと東京リージョン、アメリカ、ヨーロッパユーザーだとUS-central・・・
という風に振り分けて画像をアップロードし、UrlDowonloadする。


#まとめ
まだまだ遅いですが、リージョンを変えるだけでも改善されることがわかりますね！
目安は1~2秒なので頑張ります！:fire:
暗号とセキュリティの常識

#暗号の常識４つ
暗号技術におけるすごく基本的なことをまとめてみた。

##秘密の暗号アルゴリズムは使わない
自社内で開発して秘密にした暗号アルゴリズムは危険。

####暗号アルゴリズムの秘密はいつか必ず暴かれる
秘密にしているアルゴリズムが暴かれると危ない。逆にアルゴリズムが公開されていて使われているものは、暴露も何もないよね、ということ。

つまり、強い暗号というのはアルゴリズムがわかっていても解読できないもの。アルゴリズムがわかると終わる暗号は弱い。

####強い暗号アルゴリズムを生み出すことは危険
強いという自信が過信につながる。
強い暗号とは、**暗号の専門家に、アルゴリズム・ソースコード・平文と暗号文を渡していても、新しい暗号文の解読に時間がかかるもの**である。

##弱い暗号は暗号化しないよりも危険
暗号化を少しでもやった方がいいだろうと弱い暗号を使うことで、過信につながる。「暗号」という言葉によって安心感が出てしまう。

##どんな暗号もいつかは解読できる
どんな暗号アルゴリズムでも、すべての鍵を試せばいつかは解読できる。それが現実的な時間内かどうかはさておき。

なので、暗号文が解読されるまでの時間と、暗号で守りたい平文の価値のバランスが重要。そんなに守る価値のないものに、時間のかかる暗号を使ってもコスパが悪い。

##暗号はセキュリティのほんの一部
暗号技術は、通信の盗聴において能力が発揮できる。だが、守るべきはそこだけではない。ソーシャルエンジニアリングという攻撃では、そもそも暗号の強さは関係ない。

高いセキュリティを保つということは、システムというものの性質を理解しなくてはいけない。システムのつながりの中で弱い部分を守らなくてはいけず、一番弱いのは人間。
Webブラウザ・JavaScriptエンジン・ECMAScript

# 初めに
JavaScriptを学ぶ上でコーディングだけでなくメカニズムを学ぶ機会があったので備忘録
的な意味も込めて記事にした。
初学者ですので間違っているとこが多々あるかもしれません。

# ブラウザとJavaScriptエンジン
**Webブラウザの種類**
- Google Chrome（グーグルクローム）
- Firefox（ファイヤーフォックス）
- Microsoft Edge（マイクロソフト エッジ
- Internet Explorer（インターネットエクスプローラー）
- Safari

*JavaScriptエンジンってなに？*...  
説明: JavaScriptが実行されるエンジン(この機能の上でJavaScriptが動く)  
**JavaScriptエンジンにも種類があり、Chromeの場合(V8)を採用している**

ブラウザ名|JSエンジン
- | -
Google Chrome|V8 
Firefox|SpiderMonkey
Microsoft Edge|近年V8に移行
Internet Explorer|30
Safari|JavaScriptCore

**この表から分かる通りV8が主要になりつつある**

# WebブラウザとJavaScriptの関係性
**ブラウザにはさまざまな機能がある**


- User Interface
- Browser Engine
- Data Storage
- Rendering Engine
- *JavaScript Engine*
- Networking
- UI Backed

JavaScriptエンジン上でECMAScriptとWebAPIsが提供されている  

**関係性**

- JavaScriptエンジン
  - ECMA Script
  - Web APIs
        - DOM API
        - WebRTC
        - Fetch API
        - XHR API
        - etc
  

V8はOSSとして提供されているため様々な環境でJavaScriptを動かすことができる
様々な環境で動かすことのできるJavaScriptを*Universal JavaScript*という

# ECMAScriptとは？？
JavaScriptの基本部分の仕様を決めているのがECMAScript。 
JavaScriptはCommunications社によって開発されたが、開発当初はブラウザ間の互換性がなかった 
そこでjavaScriptの標準化が行われた。
JavaScriptの標準化が行われ基本となる使用がECMAScriptという名前で定められた。 
**JavaScriptではECMAScriptによる基本機能意外にブラウザに関連する機能が加えられている**

# まとめ
JavaScriptはJavaScriptエンジンによって動作する
主要のJavaScriptエンジンはV8と呼ばれる
V8はOSSで様々な環境でJavaScriptを動かすことができる
様々な環境で動くJavaScriptをUniversal JavaScriptと呼ぶ
ECMAScriptはJavaScriptを標準化するために作られた基本仕様のことである
JavaScriptはECMAScriptによる基本機能の他ブラウザ関連の機能が加えられている

# 参考
https://www.javadrive.jp/javascript/ini/index11.html
ActiveDirectoryとAzure AD

# はじめに
普段業務でADやAzureADを使う場面が多いため、自分の知識のアウトプットとして簡単にまとめました。

# 目次
1. ActiveDirectory（AD）とは
2. ADの主な機能
3. AzureADとは 
4. AzureADの主な機能
5. ADとAzureADの違い
6. ざっくりまとめ

# 1. ActiveDirectory（AD）とは
WindowsServerに標準搭載されている機能の１つで、組織の管理者がユーザーを管理できる。
Windows2000から導入されている。

# 2. ADの主な機能
◆ドメイン
ADでは、会社や組織に属している「人」、PCやサーバーなどの「モノ」、ファイルやフォルダなどの「データ」といったリソースを階層的に管理できる。
ドメインとは、これらのリソースを管理する範囲のこと。

◆ドメインコントローラー
ユーザーIDとパスワードを使ってユーザー認証を行っていて、どの部署がどのデータにアクセスしていいのか、その部署には誰が所属しているのか、誰がどのPCを利用しているのか、といったリソース間の関係性を管理することができる。
ドメインコントローラーとはこの管理するシステムのこと。
データの読み取りやデータの削除可能など細かく設定することが可能で、部署や役職ごとに管理単位（グループ）を作っておくことで、同じ属性を持った人に一括で権限適用することができるため、リソースごとに設定する手間も省ける。

# 3. AzureADとは
Microsoftが提供している、クラウド版のAD。
クラウド上のサービスを一括管理できたり、SSO連携させたりできる。

# 4. AzureADの主な機能
◆ID管理
通常のユーザーIDとパスワードに加えて、「生体認証」「二段階認証」「デバイス認証」などが利用でき、より安全な管理が可能。

◆クラウドサービスのアカウント管理
さまざまなクラウドサービスのアカウントを管理でき、Microsoftが提供しているサービス以外のサービスも活用可能で、シングルサインオンでアクセスすることも可能。

◆アプリケーション管理
ユーザーごとに利用できるアプリを制限することができる。

# 5. ADとAzureADの違い
◆利用目的/承認方法が異なる
ADはオンプレミスのアカウントを利用し、社内システムやリソースを認証させるための基盤。
AzureADはクラウドサービスを利用するアカウントに対して認証する基盤。

◆認証プロトコルが異なる
ADは認証では「Kerberos」、ディレクトリへは「LDAP」を使用している。
AzureADは「OpenID Connect」「SAML」などの様々なインターネット標準プロトコルに対応している。

◆デバイス管理の方法が異なる
ADは会社や組織が定めたグループポリシーを適用し、デバイスを管理。
AzureADはIntuneというツールを併用して、Azure ADとIntuneに登録したデバイスの会社のルールを適用し、デバイスを管理。

# 6. ざっくりまとめ
ADは社内ネットワーク内での利用を想定していて、AzereADはクラウドサービスに対応しているため、最近増えてきているテレワークやオンライン授業などの活用に対しAzureADの利用が増えてきそう。
仮想化ツールについて

## コラム

Windows10上で利用できる仮想化ツールには下記の３種類がある。

- VirtualBox
- VMware Workstation Player
- Hyper-V


Hyper-Vはマイクロソフト社から出ており、Proエディションにのみ標準搭載されている。Homeエディションでは使えない。コンシュマー向けではないようです。（しかし、Windows UpdateをインストールするとHomeエディションでも動かせるようになるようです）

マイクロソフトが出しているLinuxのWSL2をWindows10にインストールしようと思ったら、否応なしにHyper-Vが選択されることになる。WSL2はHyper-Vでしか動作しないため。つまり、VirtualBoxやVMware Workstation Player上でWSL2を動かしたいと思っても動かすことはできない。とはいっても、Hyper-VはWSL2専用の仮想化ツールといったわけではなく、Hyper-V上で、UbuntuやCentOSを動かすことはできる。

上記３種類の中で一番人気なのは恐らくVirtualBox。VMware Workstation Playerも悪いわけではない。VirtualBoxとほぼほぼ同じように使えるようではある。

また、仮想化をするには上記３種類の他に、Dockerという選択肢もある。Dockerについてだが、大きく２種類のツールが存在している。

- Docker Toolbox

このツールを使うと、バックでVirtualBoxが動く。Docker社が開発しているが、既に開発が停止されており、公式サイトによると今後の利用は非推奨と記載されている。レガシーになりつつある。

- Docker Desktop for Windows

Docker Toolboxに代わる新しいツールがこれになる。Docker Toolboxと異なる点は、バックで動作する仮想化ツールが、VirtualBoxからHyper-Vに変わった点だ。

Docker Desktopには２種類存在しており、マイクロソフトが出しているWSL2版とDocker社が出しているHyper-V版とが存在している。共にHyper-Vを採用している。（マイクロソフトに屈したかDocker社よ）

色々と存在する仮想化ツールであるが、VirtualBoxとHyper-Vは、相性がよくないことが知られている。VirtualBoxが入ってる環境にHyper-Vをインストールすると、VirtualBoxが動作しなくなる不具合が発生するのだ。（共存させる裏テク？のようなのはあるようではあるが）つまり、VirtualBoxを使っていて、そうとは知らず、Docker Desktop for WindowsをインストールするとVirtualBoxが動かなくなってしまう。Hyper-Vが有効になってしまうためだ。VirtualBoxを使っていて、WSL2をインストールしても、Hyper-Vが有効になってしまう。（インストーラーに注意喚起メッセージでも入れて欲しいものだ）

どこまでいっても、マイクロソフト製品を使い続けている限り、エンジニアの苦悩はなくならないのだろうか。
poetryを使って外部モジュールからimportできるようにパッケージングする

- pythonモジュールをパッケージングして、pip installしたのちに別モジュールでimportして使いたい
- poetryを使うことでパッケージングは簡単にできたが、肝心な```別モジュールでimportして使う```ところでハマったのでやり方を残す

## やったこと
pyproject.tomlにて```[build-system]```を下記のように設定

```
[build-system]
requires = ["setuptools", "wheel"]
```
QGISを簡単にWEB公開するためのLizmapの体験用のサイトを立ち上げました。

※Lizmapの体験用のサイト立ち上げについて
GISの世界も急激にQGISが素晴らしいアプリに仕上がってきているのと同時に，WEBでの公開アプリも仕上げってきています。
残念ながら，日本語化がされているアプリが少なかったので，自由に日本語化が可能で，性能に満足のいくlizmapを日本語化し，体験用サイトを立ち上げました。
よかったら，ご利用ください。
http://lizmap.yamakun.net/lizmap/

※情報共有について
継続的な運営のためフェイスブックを立ち上げましたので，興味のある方は今後の情報共有の場としてご利用いただければ幸いです。
https://www.facebook.com/groups/lizmapusergroupjapan

※日本語化ご協力のお願い
日本語化をお手伝いしていただける方も併せて募集しております。
https://www.transifex.com/3liz-1/lizmap-locales/dashboard/
Ubuntuに最新バージョンのPythonをインストールする

ubuntu20.04に最新のPython3.10.0をインストールする


###Ubuntuのバージョン確認。
cat /etc/lsb-release

DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.3 LTS"

###アーキテクチャは64bit。
arch
x86_64

###ビルド環境の準備
sudo apt update
sudo apt install build-essential libbz2-dev libdb-dev \
  libreadline-dev libffi-dev libgdbm-dev liblzma-dev \
  libncursesw5-dev libsqlite3-dev libssl-dev \
  zlib1g-dev uuid-dev tk-dev

###ソースコードのダウンロード
Python Japanのダウンロードページ
https://pythonlinks.python.jp/ja/index.html


###ダウンロードコマンド
wget https://www.python.org/ftp/python/3.10.0/Python-3.10.0.tar.xz
 
###解凍コマンド
tar xJf Python-3.10.0.tar.xz


###ビルドコマンド
cd Python-3.10.0
./configure
make
sudo make install

###再起動
reboot

###バージョン確認コマンド
python3 -V
Python 3.10.0
VGG16によるファインチューニングで胸部X線画像における肺炎の分類をする

# 概要・目的

**Kaggle で公開されているデータセットを使って
胸部 X 線画像から正常 (Normal) か肺炎 (Pneumonia) を分類する**

* 画像データ数は合計5856枚 (train: 5216, val: 16, test: 624)
* 画像サイズはデータによってまちまち
* trainデータの Normal とPneumonia の枚数の差が大きい (Normal: 1341, Pneumonia: 3875)
* テストデータでの accuracy: 95 % となった

<img width="600" alt="original image" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/862466a0-9f17-007c-123e-8910fe2dd8dd.png">

(画像出典: https://data.mendeley.com/datasets/rscbjbr9sj/2)
(Kaggle: https://www.kaggle.com/paultimothymooney/chest-xray-pneumonia)

# 採用アルゴリズム
## 画像の前処理

### 画像データの不要な部分をトリミング

 * 画像両側にうつる背景部分を削除し、分類に必要な部分のみを残す狙い
 *  画像の加工は以下の3種類について学習し、比較した
    * a. 画像を引き延ばさず、224×224 pixel に合わせる
    * b. 画像の両側をトリミングしたうえで 224×224 pixel に引き延ばす
    * c. 画像をトリミングせずに224×224 pixel に引き延ばす
 * テストデータでもっとも精度のよかった (b) を採用した

<img width="750" alt="squared images" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/45a9ebc6-9876-ad36-3646-4c866701ee93.png">

### 訓練、検証データの Normal:Pneumonia 比が同じになるよう分割

訓練データは Normal と Pneumonia の枚数がそれぞれ1341枚、3875枚と大きな開きがある。

これらのデータをそのまま結合して分割すると、訓練データにほとんど Normal の画像が無いといった事態が起こりうる。

Normal のデータ、Pneumonia のデータそれぞれを8:2 の割合で訓練データと検証データに分けることで、ばらつきを無くした。

<img width="600" alt="squared images" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/f65d1f2b-cb03-2fa9-d378-17aa8914f86d.png">


## データの学習
### データの拡張（回転、拡大、平行移動）

過学習を防ぐために、Keras の ImageDataGenerator を用いて、バッチごとにランダムに回転・拡大・平行移動を施した。
他にも明暗を変化できるが、すべて Pneumonia と予測したため不採用。

 (どうやらImageDataGenerator上で問題があるよう 参考: https://qiita.com/Kuru-chan/items/3365d48b3345d2b9cfd2)

回転・拡大・平行移動の最大値および最小値は、 3つのの場合を比較し、以下を採用。

* 回転: -20～20度
* 拡大: MAX 15%
* 平行移動: MAX 15%

### VGG16を用いてファインチューニング、学習の進行とともに学習率を減少

今回は転移学習によく用いられるVGG16を使用した。

最後の畳み込み層 (conv5) がある部分のみ訓練データを学習させ、ファインチューニングした。

学習が進行するにつれ、精度の改善が見られなくなるため、学習の後半では、徐々に学習率を減少させるようにした。

<img width="400" alt="Learning Rate" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/d57289be-65f1-402a-3740-e11208226b68.png">

# テストデータでの予測結果

* Normal は Pneumonia と比較して学習画像が少ないため、精度が比較的低い
* 学習回数 (epoch 数) は40回に設定しているが、80回でもほとんど同じ結果であった
* Normal の画像が少ないことを考慮してNormal の重みを増やし、Pneumonia の重みを減らしてもほとんど同じ結果であった

<img width="600" alt="Result" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/75e6b4ab-f5f2-b3af-e57c-a3fec39d68b5.png">

<img width="750" alt="binary cross entropy" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/854965/c8ef60f5-dfac-cb7e-897d-2097b658c9ef.png">


今回は試していないが、画像ごとにトリミング幅を調整することでさらなる精度向上が望める。

その他、訓練データに偏りがあることへの良い改善策が見つかると、1%程度精度が向上するかもしれない（希望）。

Githubでコードを公開しています

https://github.com/sotamorita/Chest-Xray/tree/main
Git 基本操作


プライベートメモ

環境
---
- リモートリポジトリ: GitHub
- git version 2.32.0.windows.2


図
---
https://docs.google.com/presentation/d/1KwV3xsd0ywUsy8E80Gb7BCL6kFCg5rf5bbd-UbzPJNU/edit#slide=id.gf71a306e6b_0_69
[シリーズ] "非K8s環境" で Prometheus を導入してみる


## 概要

変則的だが、職場の "**非K8s環境**" で Prometheus を導入することになったので
調査・導入検討をしてみたときの記録である.

Zabbix ユーザー視点でも少し記載している.

|コンテンツ|一言|
|:--|:--|
|[[01] "非K8s環境" で Prometheus を導入してみる ... Zabbix4.0との比較](https://qiita.com/robozushi10/items/1b1d244a1cae646b6039)||
|[[02] "非K8s環境" で Prometheus を導入してみる ... Promtheus と Grafana の導入](https://qiita.com/robozushi10/items/4c89b85bafe19bbd4c89)||
|[[03] "非K8s環境" で Prometheus を導入してみる ... NodeExporterを使ってみる](https://qiita.com/robozushi10/items/2b876eb25b7e69bcf277)||
公式サイト「初めてのVRアプリを構築する」をやってみる

#ちゃんと動作した！
- 引っかかったのは、ソースファイルが日本語モードでは　完全に表示されていないところ！
- それ以外は　チュートリアル通りにすれば　ちゃんと動きました！
- Unity version 2021.1.22f1
- Unity Hub 2.4.5
- Build環境 MacBook Pro macOS Big Sur 11.4
- 元ネタ https://developer.oculus.com/documentation/unity/unity-tutorial/
- https://github.com/tmdoi/oculus


#2021/10/22
- Text オブジェクトの追加
- First-wallにScriptを追加した。やはり日本語ではNG。
- また　これを使った＞　[ロケールをUS指定して開くリンク](https://developer.oculus.com/documentation/unity/unity-tutorial/?locale=us)
- 再生ボタンを押して、カーソルキーで　ボールが転がった！
- ビルドもできて、Oculus内で立体に見えて動いた！
- ![スクリーンショット 2021-10-22 21.30.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237044/01e0386c-3496-c6a8-52f7-9e8c71fbfe89.png)


#2021/10/20
- Inspectorが真っ白で焦った。＞SceneWindowsでオブジェクトを選択したら表示された
- PlayerControllerのSPEEDを500に設定した

#2021/10/19
- Script のソースコードが　どうみても　おかしい。。。　なぜ？
- 言語をUSに指定して開いたら、ソースのすべてが見えた! [ロケールをUS指定して開くリンク](https://developer.oculus.com/documentation/unity/unity-tutorial/?locale=us)

```PlayerController.c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerController : MonoBehaviour
{
    // Appears in the Inspector view from where you can set the speed
    public float speed;

    // Rigidbody variable to hold the player ball's rigidbody instance
    private Rigidbody rb;

    // Called before the first frame update
    void Start()
    {
        // Assigns the player ball's rigidbody instance to the variable
        rb = GetComponent<Rigidbody>();
    }

    // Called once per frame
    private void Update()
    {
        // The float variables, moveHorizontal and moveVertical, holds the value of the virtual axes, X and Z.

        // It records input from the keyboard.
        float moveHorizontal = Input.GetAxis("Horizontal");
        float moveVertical = Input.GetAxis("Vertical");

        // Vector3 variable, movement, holds 3D positions of the player ball in form of X, Y, and Z axes in the space.
        Vector3 movement = new Vector3(moveHorizontal, 0.0f, moveVertical);

        // Adds force to the player ball to move around.
        rb.AddForce(movement * speed * Time.deltaTime);
    }
}
```

#2021/10/17
- floorを作った
- player-ballを作った
- 壁を4つ作った
- カメラのライティングを調整した
- ステップ３で一旦作業中断

#2021/10/12
- 4つのマテリアル用の色を作った

#2021/10/10
- [これの前作：YouTubeみながらQuest2のBuild and Runできた](https://qiita.com/tmdoi/items/59fc039eb83f95e7dad1)
- 着手日 2021/10/10
- [元ネタ：初めてのVRアプリを構築する](https://developer.oculus.com/documentation/unity/unity-tutorial/?locale=ja_JP)
- [前提条件](https://developer.oculus.com/documentation/unity/unity-tutorial/?locale=ja_JP#prerequisites)の確認
- Unity設定を構成するを順番に行ったが、以下の２箇所、不安がある
- ■ビルトインXRプラットフォーム統合を使用する:
- ■[Androidマニフェストファイルを生成する](https://developer.oculus.com/documentation/unity/unity-conf-settings/#generate-manifest)
- 後日は、[ここから再開する：基本概念](https://developer.oculus.com/documentation/unity/unity-tutorial/#basic-concepts)
![スクリーンショット 2021-10-22 21.30.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/237044/c5b51374-b775-c36c-f4d6-da3a4c092a27.png)
[AtCoder][ABC132D] 仕切り法を使った組み合わせ問題を解く


この問題の解説を自分なりに咀嚼して書く。
Atcoder 132 D - Blue and Red Balls 

https://atcoder.jp/contests/abc132/tasks/abc132_d

# 要約
**赤と青の2種類のボールを並び替える問題。
赤ボールはN-K個、青ボールはK個存在する。
青ボールがiグループに孤立するような並び替えの組み合わせを求める。**

それぞれのボールは区別ができない。
下記の例では青ボールは2グループに孤立している。
```BBB RRR BBB RRR```
※Bを青ボール、Rを赤ボールとする。

# STEP1. 赤ボールと青ボールの組み合わせを考える

青ボールのグループ数をiとする。
``` B B B ```
このとき、赤ボールは青ボールの間に少なくとも1つ置く必要があるので、i-1グループ必要となる。
``` B R B R B ```
赤ボールは両端にボールを置いてもいいのでグループ数は最大i+1グループとなる。
``` R B R B R B R ```

ここで青ボールをiグループに１つ配り、赤ボールをi-1グループに予め配っておくことで今回の問題を下記のように言い換えることができる。

**青ボールがk-i個、赤ボールがN-k-(i-1)個存在する。
青ボールをiグループ、赤ボールをi+1グループに分ける組み合わせの数を求めよ**

# STEP2 1種類のボールを複数のグループに分ける組み合わせを考える。

まずは下記の関数を定義する。
```f(k, i) := k個のボールをiグループに分ける組み合わせ```

これは組み合わせのグループ分け問題に帰着できる。
グループ分け問題で注意する必要があることが３つある。

1. モノが区別できる
2. グループが区別できる
3. グループのモノ数の指定がある（ないとすれば0個のグループはOKか）

https://hiraocafe.com/note/kumiwake.html

今回の問題では分ける対象のボールは区別できない
しかしグループは区別する
例えば、XXX XXとXX XXXは同じではないので区別できる。
0個のグループはもOK。（1つ以上のボールが必要なグループには既にボールを配っている）

よって、今回は仕切り法を使って関数を定義
fの実装は仕切り法を使ってこのようになる。
```f(k, i) := comb(K+i-1, i-1);```

# 結論
全ての組み合わせは下記の式で表すことができる。
```f(k-i, i)*f(N-k-(i-1), i+1)```

# 実装
mintとcomb実装は後日別記事で解説予定

```c++
mint f(int n, int k) {
    return comb(n+k-1, k-1);
}

int main() {
    int n, k;
    cin >> n >> k;
    for (int i=1; i<=k; i++) {
        mint blue = f(k-i, i);
        mint red = f(n-k-i+1, i+1);
        mint ans = blue*red;
        cout << ans.x << endl;
    }
}
```
【BSOD】Windowsで意図的にブルースクリーンを発生させる方法5選

# 本記事の対象者

・ダンプファイルの解析をする目的で、__意図的にブルースクリーンを発生させたい人__
・セキュリティ関連の技術者で、__どうしたらWindowsでブルースクリーンが発生してしまうのか知りたい人__
・~~Microsoftに恨みがあって、__WindowsをBSODにしてやりたい人__~~

:::note alert
他人のコンピューターでBSODを発生させると、刑事・民事上の責任を問われる可能性があります。必ず仮想環境で実行してください。
:::

# 方法1. 重要なプロセスを〇す

Windowsの続行が困難な程重要なプロセスが強制終了された場合、BSODになります。

具体的には、「wininit.exe」「ntoskrnl.exe」「svchost.exe」などです。

``` bsod.bat
taskkill /IM:svchost.exe /F
```

:::note warn
通常のWindows環境では「wininit.exe」などをセキュリティ上の理由で強制終了できない場合があるらしいです。
:::

# 方法2. システム破壊

WindowsディレクトリのSystem32あたりを管理者権限で削除して再起動すると、ブルースクリーンになります。

``` bsod.bat
rem 注意: 管理者権限で実行しないとアクセス拒否されてブルースクリーンになりません
rd /s /q %systemroot%/System32/
```

ただし、__実行には時間がかかる上に復旧するにはOSを再インストールする他ない__ので、あまりオススメしません。

# 方法3. 開発者用の方法を使う

以下のレジストリに「__CrashOnCtrlScroll__」という名前の__32ビットキー__を作り、値を「__1__」とします。

```
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\kbdhid\Parameters
```

OSを再起動し、キーボードの右側のCtrlを押しながら「Scroll Lock」を2回押すとブルースクリーンになります。
ただし、右Ctrlの無いキーボードを使っている場合には実行できません。ご注意を。

# 方法4. 脆弱性(バグ)を利用する

ブラウザから、以下のURLを開くとBSODが発生します。

```
\\.\globalroot\device\condrv\kernelconnect
```

以下、 https://security.srad.jp/story/21/01/19/1922232/ から引用
>問題のパスは「\\.\globalroot\device\condrv\kernelconnect」というもので、先日NTFSの脆弱性を公表して話題になったJonas Lykkegaard氏が昨年10月、BSoDを引き起こす方法としてさらっとツイートしていた。当時は特に注目されなかったが、NTFSの脆弱性公表に伴って発掘されたようだ。このパスはコンソールドライバー(condrv.sys)を示すWin32デバイス名前空間パスだが、Lykkegaard氏はカーネルモード/ユーザーモードのプロセス間通信に使うものだと考えているという。このパスを使用するには属性の付加が必要だが、属性を付加しないでアクセスした場合に適切なエラーチェックが行われず、BSoDが発生するとのこと。

私の手元のEdge環境では、「ファイルが見つかりません」となってしまい、実現できませんでしたが、__2021年の2月ごろまでのビルドのWindowsであれば実現できる__らしい。(根拠無し)

# 方法5. 外部アプリを使う

「NotMyFault」と呼ばれる、意図的にブルースクリーンを発生させるアプリを利用すればクリック一回でBSODを出せます。

https://docs.microsoft.com/ja-jp/sysinternals/downloads/notmyfault

こちらは__エラーの種類や、ブルースクリーンの色を変更できる__(もはやブルースクリーンじゃないんだが)ので便利です。

# 最後に
BSODを発生させると、メモリーの内容が自動的に「__%systemroot%\MEMORY.DMP__」に保存されます。
あとは、このファイルを外部のツールなどで解析してください。
SNS認証におけるNot found. Authentication passthru.エラーについて

##概要
　SNS認証（Omniauth使用）時に（今回はGoogle認証を使用した場合となります）おいて、Google認証ページに遷移しようとすると、「Not found. Authentication passthru.」のエラーが出た場合の対処法について記載します。
　SMS認証の導入自体は、下記の記事にお世話になりました。ありがとうございます。

・[deviseとOmniAuthをRailsアプリケーションに導入しテストする](https://qiita.com/yuki_0920/items/003d8b1c73352378188d)

#対処法
　該当部分は、app/views/devise/shared/_links.html.erbにある、認証画面への遷移用リンクとなります。（user_google_oauth2_omniauth_authorize_pathでエラーが生じます）

```app/views/devise/shared/_links.html.erb（該当部分のみ抜粋）
<%- if devise_mapping.omniauthable? %>
  <%- resource_class.omniauth_providers.each do |provider| %>
　　#今回問題となったリンク（自動生成→自身で少し訂正）
    <%= link_to 'Signin with Google', user_google_oauth2_omniauth_authorize_path, method: :post %><br />
  <% end %>
<% end %>
```


　まず、以下の記事の内容をお試し下さい。

・[SNS認証ログインでNot found. Authentication passthru.が表示されたときの対処方法](https://qiita.com/hasegawa-naoto/items/82c2fc790c687b814cc8)
・[Rails5でrails で google認証ができない「Not found. Authentication passthru.」](https://qiita.com/robocka/items/b70901040db928f4488a)

 　こちらの記事の内容で治れば、それでよかったのですが、私の場合はこれを試してもエラーがなくなりませんでした。
　結論から申し上げると、config/initializers直下に、「omniauth.rb」を作成していただき、以下の内容を記載するとエラーを突破することができました。

```omniauth.rb
Rails.application.config.middleware.use OmniAuth::Builder do
  OmniAuth.config.allowed_request_methods = [:post, :get]
end
```

　こちらに関しては、現在私が利用させてもらっているスクールのメンター様に教えていただいた方法になります。
　正直完全には理解できておりませんが、OmniAuthでの認証時にPOSTメソッドを許可する記述だそうです。これがない状態だと、うまくPOSTメソッドが機能しない状態だったそうです。

　これで私の場合は認証機能がうまく動きました。どなたかの参考となれば幸いです。
Windows+docker+anacondaで分析環境構築(リンク集)


windowsでの分析環境構築にあたって、Dockerの中にanacondaをインストールして更にその中でanacondaの仮想環境を設定して分析環境とします。

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

以下のリンクからDocker Desktop for windowsをダウンロードします。

https://hub.docker.com/editions/community/docker-ce-desktop-windows/

なお、実行時のトラブルシューティングは以下;

https://qiita.com/LemonmanNo39/items/b1b104e7fb609464727b

##2. docker にanacondaイメージをインストール

power shellで以下を実行します。（以下すべてpower shell内）

``` .bash
docker pull continuumio/anaconda3
```

##3. docker にコンテナを生成

インストールしたanacondaイメージからコンテナを生成します。

``` bash
docker run --name CONTAINER_NAME -it -p 8888:8888 -v "$(pwd):/home" continuumio/anaconda3 /bin/bash
```

なお、ctrl+d などで一度ストップしたコンテナのインタラクティブでの再開は以下。

``` bash
docker start CONTAINER_NAME -i
```


##4. 仮想環境の設定

コンテナ内でバージョンの異なるpython等を利用したいときのために、仮想環境を設定します。

```
conda create -n ENV_NAME python==X.X
conda activate ENV_NAME
```

##5. Jupyter notebookの立ち上げ

jupyter notebookを立ち上げます。

```
jupyter notebook --port 8888 --ip=0.0.0.0 --allow-root
```
Laravel8 Jetstream / Fortify のURLを変更する

# やりたいこと
認証とかのURLを変更したい

# やりかた

## Fortify

`FortifyServiceProvider`の`register`メソッドに`Fortify::ignoreRoutes();`を追加。

```php
~略~

class FortifyServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        Fortify::ignoreRoutes();
    }

~略~
```

`routes`フォルダ内に`fortify.php`を作成する。

`vendor\laravel\fortify\routes\routes.php`の中身をコピーして先ほど作成した`fortify.php`に貼り付ける。
([fortifyはなぜかpublishが用意されていない](https://github.com/laravel/fortify/pull/202))

あとはRouteServiceProvideにルーティングとして登録する。

```php
class RouteServiceProvider extends ServiceProvider
{
~ 省略 ~
    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

            // 追加
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/fortify.php'));
        });
    }
```

あとはよしなにルーティングをいじる。

## JetStream

`JetstreamServiceProvider`の`register`メソッドに`Jetstream::ignoreRoutes();`を追加。

```php
~省略~

class JetstreamServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        Jetstream::ignoreRoutes();
    }
```

Jetstreamのルーティングファイルを公開する。

```bash
php artisan vendor:publish --tag=jetstream-routes
```

あとはRouteServiceProvideにルーティングとして登録する。

```php
class RouteServiceProvider extends ServiceProvider
{
~ 省略 ~
    /**
     * Define your route model bindings, pattern filters, etc.
     *
     * @return void
     */
    public function boot()
    {
        $this->configureRateLimiting();

        $this->routes(function () {
            Route::prefix('api')
                ->middleware('api')
                ->namespace($this->namespace)
                ->group(base_path('routes/api.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/web.php'));

            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/fortify.php'));

            // 追加
            Route::middleware('web')
                ->namespace($this->namespace)
                ->group(base_path('routes/jetstream.php'));
        });
    }
```

あとはよしなにルーティングをいじる。

認証系のルーティングでauthにして1ファイルにまとめたりしても良いかも
ターミナルでカレントディレクトリにあるファイルを実行するとき、./(ドットスラッシュ)が必要なのはなぜ？

#前書き
ちょっとしたプログラムを書いて実行するとき、浮かんでは放っといた（←よくない）ある疑問を調べてみたのでまとめてみた。
**「なぜ、ターミナルでカレントディレクトリにあるファイルを実行するときファイルの名前だけでは実行されないのか。」**

#"."と"/"の意味
UNIX系のOSではそのファイルまでの絶対パスまたは相対パスを書くことでそのファイルを実行できる。

それなら、cdでカレントディレクトリに移動したらそこのファイルはファイル名だけで実行できるのではないか。

デスクトップに置いたtestフォルダ内のhogeファイルで試してみる。

```
$ cd /Users/ユーザー名/Desktop/test
$ hoge
-bash: hoge: command not found
```

うまくいかない。メッセージを見ると「hogeなんてコマンド見つからないよ」と言われている。コマンドは実行するファイルを指示することなので、「hogeなんてファイル見つからないよ」と言われているようなものである。
<br>
ここで、このファイル名の頭に**"./"**(ドットスラッシュ)をつけてみる。

```
$ ./hoge
hogehoge
```

実行されてちゃんとhogehogeと返してくれた。それには理由がある。

まず、UNIX系のOSでは**"."**(ドット)に**「カレントディレクトリ」**の意味がある。

それに**「ディレクトリの区切り」**を意味する**"/"**(スラッシュ)をつけることで、上記はhogeへの相対パスを書いていることになるのだ。

よって./hogeはうまく実行されたのである。

|記号|意味                                                                      |
|:-:|:-------------------------------------------------------------------------|
| . | **カレントディレクトリ**。<br>..と2つ並ぶと1つ階層が上のディレクトリを示す。        |
| / | **ディレクトリの区切り**。<br>1番最初に書かれている/だけ**ルート(最上位の階層)**という特別な意味を持つ。|

#なぜ、ファイル名だけでは実行できないのか
###それは、PATHに登録されていないから
./をつければ実行できる理由は分かったが、なぜカレントディレクトリのファイルはファイル名だけでは実行できないのか。

それは、UNIX系OSではファイル名だけで実行するとそのファイルを探しに環境変数のPATHを参照しにいくからである。

PATHとは**「実行ファイルがある場所の絶対パスが保存されている」**OSが持つ変数であり、カレントディレクトリのパスはそこには含まれていない。

そのため、カレントディレクトリのファイルはファイル名のみでは実行できないのである。

PATHに登録されているパスは以下のコマンドで確認できる。

```
$ printenv PATH
/usr/bin:/bin:/usr/sbin:/sbin
```

実行してみるといくつかのパスが：で区切られて表示される。
これらの場所にあるファイルのみがファイル名のみで実行できるようになっているのである。

printenvもこのパスの場所にちゃんとファイルが存在する。
それはwhichというコマンドで以下のように確認できる。何もいじってなければ以下のような結果になるはずだ。当然whichも存在する。

```
$ which printenv
/usr/bin/printenv

$ which which
/usr/bin/which
```

少し話がずれてしまったので戻そう。

つまり、どうしてもあるファイルをファイル名のみで実行したいときは、そのファイルがある場所のパスをPATHに登録することでファイル名のみでも実行できるようになる。

これが世に言う「パスを通す」である。
これについては以下の記事がとても分かりやすいので紹介したい。

https://qiita.com/Naggi-Goishi/items/2c49ea50602ea80bf015

###カレントディレクトリをPATHに登録すればいいんじゃない？（ダメです）
さて、勘の良い方はここまでで"."をPATHに登録すればカレントディレクトリのファイルをファイル名のみで実行できるようになると思われるだろうがそれは正しい、がおすすめはできない。それにより困ることがあるのだ。

簡単なものだと、PATHに登録されている別のファイルと名前がかぶることが考えられる。
名前がかぶってしまうと登録の順番によってはその時呼び出したいファイルが呼び出せなくなってしまう。

もっと深刻なものだと、セキュリティの問題がある。

カレントディレクトリのファイルなら何でもOKということは、ターミナルを開いてすぐのカレントディレクトリであるホームディレクトリでもファイル名のみで実行できるということだ。

それの何が困るのか。

例えば、ホームディレクトリによく使うコマンドの名前（cdなど）をつけた悪意があるファイルをクラッカーが置いたとする。
すると、本来のユーザは何も考えずにそれを実行してしまう可能性があるのだ。

**よって、何も考えずに"."をPATHに登録してはいけない。**

このようにちゃんとした理由があり、カレントディレクトリのファイルはファイル名のみで実行できないようになっていることが分かった。

#参考サイト
"パスが通っていない"場所の実行ファイル
・ http://ftp.lumica.co.jp/_operation/path_through.html#target_nopathexec01

カレントディレクトリのプログラムを実行するには
・ https://atmarkit.itmedia.co.jp/flinux/rensai/linuxtips/040execcaprog.html

セキュリティの考察
・ https://linuxjf.osdn.jp/JFdocs/Path-12.html

パスを通す
・ https://linuc.org/study/knowledge/349/

#あとがき 兼 自己紹介
初めまして、manaeと申します。
ここまで記事を読んでいただきありがとうございます。少し長くなってしまいました。

Birdmanという会社でDevice Developerをしております。コロナ禍入社の2年目です。
Qiitaではふとした疑問について調べたことや、勉強した技術について記事にまとめていこうと思っております。

まだまだ初心者なので間違っていることがありましたらご指摘いただけると幸いです。何卒よろしくお願いいたします。
Flutter:Invalid argument: Instance of '_JsonQueryDocumentSnapshot'

## Firestoreを使っていたときに`Invalid argument: Instance of '_JsonQueryDocumentSnapshot'`とエラーが出た

#該当のコード
```dart
Future addPost(DocumentSnapshot) async {
  final doc = thisDoc;
  await FirebaseFirestore.instance.collection('posts')
  .add({
    'DocId': doc,
  });
}
```

めちゃくちゃどうでもいいことに時間をかけてしまった。

##解決
```dart
Future addPost(DocumentSnapshot) async {
  final doc = thisDoc;
  await FirebaseFirestore.instance.collection('posts')
  .add({
    'DocId': doc.id,
  });
}
```
【Laravel】Route::resourceを使ってみよう

#はじめに
今回は、`Route::resource`を使ってCRUDのルーティングを一度に行う方法を見ていきましょう。

`version：Laravel8`

#Route::resourceを使わない場合
以下のように、1機能につき最大8個のルーティングを記述する必要があります。

```php:web.php
Route::get('/menus', [MenuController::class, 'index']);
Route::get('/menus/create', [MenuController::class, 'create']);
Route::post('/menus', [MenuController::class, 'store']);
Route::get('/menus/{theMenu}', [MenuController::class, 'show']);
Route::get('/menus/{theMenu}/edit', [MenuController::class, 'edit']);
Route::put('/menus/{theMenu}', [MenuController::class, 'update']);
Route::get('/menus/[theMenu]', [MenuController::class, 'destroy']);
```

#Route::resourceを使うと
以下のように1行で記述することができます。

```php:web.php
Route::resource('menus', MenuController::class);
```

#一部のメソッドのみ使いたい場合
##`only`で使うメソッドを宣言

```php:web.php
Route::resource('menus', MenuController::class)->only([
    'index', 'show'
]);
```

##`except`で使わないメソッドを宣言

```php:web.php
Route::resource('menus', MenuController::class)->except([
    'create', 'store', 'update', 'destroy'
]);
```
【UE4】EUWで複数ファイルのLODを一括生成・削除

-UE4.27
大量のStatickMeshのLODを一括で生成したかったのでEUWでツール作ってみた。

https://twitter.com/xxJulexx/status/1447120208842289156

イベント３つはそれぞれ、Generateボタン/Removeボタン/処理ファイル数表示をリセット
![GenerateLODs-EventGraph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102588/27a2aebf-5c58-88de-c46d-879f40981a44.png)
これ2桁以上のファイル弄るときに超必須になりそう。
LODの設定はお好きなように。

Download >> [GenerateLODs.uasset](https://xxjulexx.gumroad.com/l/HZZHzq)
*UE4.27
WPFで複数UIスレッドを作ってつらくなった話

複数UIスレッドを作ったときに、つらい思いをしたパターンの情報共有です。

# 結論を3行で

* UIスレッドを複数作ることは二度とないです
* 絶対にUIスレッドは複数作りません
* UIスレッドはMainスレッドだけです

# 前書き
ほぼ「[複数 UI スレッドを WPF でやる前にやってほしいこと](https://qiita.com/okazuki/items/698ec4d45c8286fedac1)」の話です。アプリケーションの要件的に、参照先の記事に書いてある問題点は関係ないので、ちょっと試してみようかなと。
だいたい、[MS Docsで紹介されている](https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/threading-model?view=netframeworkdesktop-4.8)由緒正しい方法ですしね。

# なにが起きたか

* `Application.Windows`を参照しただけで落ちました。サードパーティライブラリの中で参照していたので割とどうしようもない。挙動としては納得。
* `Application.ShutdownMode`がほとんど役に立たない。`OnLastWindowClose`に設定しても、Mainスレッドから表示したWindowがすべてCloseした段階でアプリケーションが終了する。そこしか監視していないんだろうなあ。


# どうしたか

UIスレッドをMainスレッドに一本化しました。そこらへんのロジックを集約していたのが吉と出て、全体への影響はほとんどなし。

# 万一、複数UIスレッドを作りたい人がいたら

単一UIスレッドに戻せるような仕組みにはしておいたほうがいいと思います。問題が起きてから切り戻せるなら、複数UIスレッドもありだと思います。
ただ、どこで問題が起きるかわからない地雷原みたいな手法なので、私はもう二度とやりません。

# 終わりに

チートシートみたいに、この問題が起きないことがわかっているなら複数UIスレッドも悪くないよ、というリストが作れたらいいですね。
私は二度とUIスレッドを複数作らないので、新しい問題を発見することはないでしょうが。

# 参考記事

* 複数 UI スレッドを WPF でやる前にやってほしいこと https://qiita.com/okazuki/items/698ec4d45c8286fedac1
* スレッド モデル https://docs.microsoft.com/ja-jp/dotnet/desktop/wpf/advanced/threading-model?view=netframeworkdesktop-4.8
C# 複数のクラスに同一のインスタンスを提供する方法

# 概要
通信するクラスや外部リソースを操作するクラスの場合、複数のクラスから操作するときに同一のインスタンスを取得する方が都合がいいことがあります。
その際の実装の例を記載しておきます。

# コード

```cs
public class UniqueClass
{
    /// <summary>
    /// 共通のUniqueClassのインスタンス
    /// </summary>
    private static UniqueClass _instance = null;

    /// <summary>
    /// インスタンスを取得
    /// </summary>
    /// <returns></returns>
    public static UniqueClass GetInstance()
    {
        if (_instance == null)
        {
            _instance = new UniqueClass();
        }
        return _instance;
    }
        
    /// <summary>
    /// プライベートコンストラクタ
    /// </summary>
    private UniqueClass() { }
}

```

# 解説
上記UniqueClassのポイントは以下の3点です。

1. staticな自分自身のインスタンス
2. 外部にインスタンスを与えるGetInstance()メソッド
3. プライベートコンストラクタ

1つずつ解説していきます。
> 1.staticな自分自身のインスタンス

これは複数のクラスに渡すためのユニークなインスタンスとなります。

> 2.外部にインスタンスを与えるGetInstance()メソッド

外部クラスからインスタンスを取得するための関数です。
1のインスタンスをリターンします。
※外部から呼び出す際は、

```cs
UniqueClass unique = UniqueClass.GetInstance();
```

のようにしてインスタンスを取得します。

> 3.プライベートコンストラクタ

privateで宣言されたコンストラクタです。
この宣言をすると外部からnewを使ったインスタンスを生成できなくなります。
間違ってnewを使用されたくないときに宣言してください。
Windows11をシステム要件を満たさないPCへインストール

個人的なメモです。

https://support.microsoft.com/ja-jp/windows/%E6%9C%80%E5%B0%8F%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E8%A6%81%E4%BB%B6%E3%82%92%E6%BA%80%E3%81%9F%E3%81%97%E3%81%A6%E3%81%84%E3%81%AA%E3%81%84%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AB-windows-11-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B-0b2dc4a2-5933-4ad4-9c09-ef0a331518f1

を読んで、理解して、Windows11をシステム要件を満たさないPCへインストールする実験をしてみた。

# PC正常性チェック

　WindowsPCHealthCheckSetup.msiをインストールし、PC正常性チェックを行うと、

> このPCは現在、Windows11システム要件を満たしていません
>
> - PCはセキュアブートをサポートしている必要があります。
> - TPM2.0がこのPCでサポートされ、有効になっている必要があります。  
> TPM TPM1.2
> - プロセッサは現在、windows11でサポートされていません。  
> プロセッサ:Intel Core i3-4000M cpu @ 2.40GHz

のように表示された。CPUは第4世代で、メモリは4GBです。

# セキュアブートへの対応

https://docs.microsoft.com/ja-jp/windows/deployment/mbr-to-gpt

　UEFIモードに対応しているので、上記を参考に、`MBR2GPT.EXE` を使って、ディスク上のデータを削除せずに、ディスクをマスターブートレコード(MBR)からGUIDパーティションテーブル(GPT)パーティションスタイルに変換した。

　コマンド プロンプトで

```batchfile
MBR2GPT /convert /allowFullOS
```

オプションについて

- `/convert`　ディスクの検証を実行し、すべての検証テストが成功した場合に、変換を実行する。
- `/disk:<diskNumber>`　GPT に変換するディスクのディスク番号を指定。 指定されていない場合には、システムディスクを変換する。
- `/allowFullOS`　Windows環境の実行中に、ディスクの変換を有効にする。

　その後、BIOSでUEFIモードで起動するように変更した。

# TPMとCPUへの対応

https://support.microsoft.com/ja-jp/windows/windows-11-%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95-e0edbbfb-cfc5-4011-868b-2ce77ac7c70e

　TPMはTPM1.2だったので、上記を参考に、次の様にレジストリキーの値を作成して、TPMとCPUのチェックをバイパスした。

　レジストリ エディターで、HKEY_LOCAL_MACHINE\SYSTEM\Setup\MoSetupに、AllowUpgradesWithUnsupportedTPMOrCPU キーを作成する。
AllowUpgradesWithUnsupportedTPMOrCPU キーに REG_DWORD を作成し、値を 1 にする。

　これで、システム要件を満たさないPCで、Windows10 21H1 から Windows11 へアップデートすることができた。
[Ruby] AtCoder過去問 B - Exponential

##はじめに
AtCoder過去問B問題をRubyで解いてみました。
よろしくお願いします。

問題はこちらから確認してください↓

https://atcoder.jp/contests/abc097/tasks/abc097_b

##B - Exponential
まずは入力をうけとります。
また、１が入っている配列を作っておきます。

```ruby
x = gets.to_i
ary = [1]
```

このあとwhile文を使うのですが、そのとき1×1はどれだけ繰り返しても1で無限ループへ突入するため、配列には初めから1を入れておきます。

1は初めから入っているので2~xまでのeach文を作成します。iという数字はこの後の処理の中でも固定しておきたいのでコピーとして変数jを用意してiを代入しておきます。

```ruby
x = gets.to_i
ary = [1]
(2..x).each do |i|
  j = i
```

続いてwhile文を作成します。i × jの答えがxより大きくなったときは処理を終了させます。
i × jの答えがx以下の間はi × jを行いjに代入し、そのjを先ほど作成した配列に入れていきます。


```ruby
x = gets.to_i
ary = [1]
(2..x).each do |i|
  j = i
  while i * j <= x
    j = i * j
    ary << j
  end
end
```

最後に出来上がった配列の中で一番大きい数字を出力すれば完成です。

```ruby
x = gets.to_i
ary = [1]
(2..x).each do |i|
  j = i
  while i * j <= x
    j = i * j
    ary << j
  end
end
 
puts ans.max
```
RDS Proxy のリーダーエンドポイントに IAM 認証を使う方法

## TL;DR

- sslmode は `verify-full` ではなく `verify-ca` にする
- あとは[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy-connecting.html#rds-proxy-connecting-iam)の通りにやればOK

## 発端

~~どうやら IAM 認証が使えるのはメインの Read/write エンドポイントだけみたいですね。~~
→ AWS のサポートにて方法を教えてもらいました。

メインのエンドポイントとリーダーエンドポイントそれぞれで cli でトークンを作成して接続してみましたが、リーダーエンドポイントのときは次のエラーになりました。

```
sql: server common name "*.proxy-●●●●●●●●●●●.ap-northeast-1.rds.amazonaws.com" does not match host name "testforsupportcase-read-only.endpoint.proxy-●●●●●●●●●●●.ap-northeast-1.rds.amazonaws.com"
```

## 原因と対策

リーダーエンドポイントのホスト名に `.endpoint.` があるため、証明書のコモンネームと不一致とされているようです。
コモンネームの一致まで検証しないようにすることで接続できるため sslmode を `verify-full` ではなく `verify-ca` にすれば接続できるということでした。

## Python (Psycopg2) でのRDS Proxy IAM認証 接続サンプルコード

`./AmazonRootCA1.pem` というパスで [AmazonRootCA1.pem](https://www.amazontrust.com/repository/AmazonRootCA1.pem) ファイルが置かれている想定です。
Lambda であれば lambda_function.py と同じフォルダに置いておけばOKです。

```py
import psycopg2
import boto3

def connect_with_iam(proxy_endpoint, dbname, username, region, port="5432"):
    client = boto3.client(service_name='rds', region_name=region)
    token = client.generate_db_auth_token(DBHostname=proxy_endpoint, Port=port, DBUsername=username, Region=region)

    con = psycopg2.connect(
        host=proxy_endpoint,
        port=port,
        dbname=dbname,
        user=username,
        password=token,
        sslrootcert='AmazonRootCA1.pem',
        sslmode='verify-ca',
    )
    con.set_client_encoding('utf-8')
    return con
```

IAM Role の設定等、その他の手順は[ユーザーガイド](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/UserGuide/rds-proxy-connecting.html#rds-proxy-connecting-iam)に従えばできます。

参考: IAMポリシー

```json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "rds-db:connect",
            "Resource": "arn:aws:rds-db:{{REGION}}:{{AWS_ACCOUNT_ID}}:dbuser:{{PROXY_ID}}/{{DB_USER}}"
        }
    ]
}
```

`{{PROXY_ID}}` はプロキシARNの最後の `prx-xxxxxxxxxxxxxxxx` の部分

### 参考記事

https://dev.classmethod.jp/articles/rds-proxy-adds-read-only-endpoints-for-amazon-aurora-replicas/

https://aws.amazon.com/jp/premiumsupport/knowledge-center/rds-postgresql-connect-using-iam/

https://www.postgresql.jp/docs/11/libpq-ssl.html

※PostgreSQL sslmode の説明は↑を参照
[postgresql] serial型のカラムのみのテーブルにinsertする



こんなテーブルがあったとする。

```
> create table hoge (id serial);
```

インサートするにはこうする。

```
> insert into hoge values(default);
```


これだとエラーになるのでダメ。


```
insert into hoge values();
```


### ここに書いてあった
https://stackoverflow.com/questions/12336789/in-postgresql-how-do-you-insert-into-a-table-with-only-one-identity-column/12336849
DDD（ドメイン駆動設計）の勉強＆実践記録（二）

###要件定義とドメインモデリング
####本記事の内容概要
（Uber eatsみたいな）オンラインフード注文・配達アプリ開発を例に下記の内容を説明します。
　・業務分析のやり方（Event Strom）
　・ドメインモデリング
　・ドメイン、サブドメイン、コンテキストの判断方法

####業務分析のやり方
DDD（ドメイン駆動設計）で一番重要なのは業務分析ですが、お客様と要件定義を行う際に下記の壁があります。
　・お客様は自社業務に詳しいが、IT技術は何を実現できるかが分からない。
　・SEはIT技術でどんなものを実現できるかが分かるが、お客様の業務が分からない。
そのため、どうお互い理解するかが重要となります。

**DDDでは業務分析のやり方は以下となります。**
　①　SEは積極的にお客様の業務（特に業務用語の意味）をできるだけ事前把握する。
　②　Event Stromでお客様との要件を聞き出す。
　③　ドメインモデリングやUMLモデルを作成し、お客様と合意を取る。
　④　①～③を繰り返して、完成まで資料をブラッシュアップする。

#####イベントストーム（Event Strom）とは？
実際業務で起こっているイベントをベースにドメインモデリングをする方法です。
ポイント：
　・ブレーンストーム（Brain Strom）会議
　・業務専門家（顧客）、プロダクトマネージャー、開発専門家が参加
　・業務で起こっているイベントを全部網羅すること

#####実際分析してみよう！
モデリング時に下記ツールを使用しています。（なんとこれにFree versionがあります！！）
Visual Paradigm Online　：　https://online.visual-paradigm.com/

######・Event Stromでお客様との要件を聞き出す。
仮に今回アプリ開発についてBrain Strom会議の結果は以下のようになります。
※データベースモデリングするときに詳しく考えていきたいため、ユーザ情報（住所、名前、クレジットカードなど）、レストラン情報（場所、メニューなど）と配達員情報（名前など）は図に省略されています。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/7c4c3fa7-753c-e741-6057-12774dab9529.png">

######・ドメインイベントをまとめる
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/3c33cd60-57c7-eeb5-9dee-9619d794d7e0.png">

######・ドメイン、サブドメイン、コンテキストを見極める
使用されている用語：
　・問題領域：実際の顧客業務と起こっている問題のこと
　・サブ問題領域：問題領域をブレイクダウンしたもの
　・コンテキスト：サブ問題領域を中心にしたドメインモデル（単一責任の原則）
　・コアドメイン：業務にとって重要なもの
　・サブドメイン：コアドメインをサポートする業務
　・汎用ドメイン：汎用的な業務
※見る視点によって、コアドメイン、サブドメイン、汎用ドメインが異なるため、顧客と十分やり取りをした後に合意する必要があります。
<img width="800" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531194/697867b6-0ea1-e23b-015b-ce1bca247de0.png">

####まとめ
本記事ではオンラインフード注文・配達アプリ開発を例にドメインモデリングをしてみました。
次回はこれをもとにマイクロサービス設計とイベント通知制御の設計をしようと思います。
VSCode で javascript/typescript の定義ジャンプ等の機能が効かないときの対処法

#### 発生した問題
vscodeで .js,.tsファイルを書いている際、以下の機能が不能になった。

- 定義ジャンプ
- マウスホバー時のポップアップ
- その他、[programmatic-language-features](https://code.visualstudio.com/api/language-extensions/overview#programmatic-language-features) 全般が効かない


#### 解決方法
ESLint の拡張機能が下記の拡張機能を無効にしてしまうらしく、

![Screen Shot 2021-10-10 at 17.29.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/676735/59f38978-a675-2054-a483-dc07d88f87e0.png)

拡張機能で `@builtin typescript` と検索し、`TypeScript and JavaScript Language Features` を有効にすると直った。

#### 参考
https://stackoverflow.com/a/56539137