OmniAICreator/Qiita-1.07M huggingface dataset:
設計書の見かたや考え方書くよー

# はじめに

皆さんこんにちは。
私は30代でPCをほとんど触ったことない状態でエンジニア転職した者です。

そんな私が転職して聞いたことや思ったことをメモ的な感じで書いて行きます。
誤字脱字あるかもですがご容赦をm(_ _)m

※あくまで私個人の意見です。

# 転職したばかりの方、転職される方へ
この記事を読んでいる方は、おそらく独学にて学習している方、現場に出ていて実際に仕事をしている方だと思います。

なので、自分はこんなサービスを作りたいから作る！！や現場ですとこれを作ってくださいなどあると思います。

自分で作りたいものを作る！！はそれでいいと思います。
それでモチベーションも上がりますし、色々調べながら作っていくので新しい発見など学びがあると思うからです。

一方で現場などで実際に初めて設計書を見たり聞いたりする方は最初意味がわからないや専門用語も多くて調べながら見ていくとそれだけで時間が刻々と過ぎていくと。

‥‥今回のお話しの焦点は入社したばかりの方やこれから転職する方に当ててやった方がいいことやその考え方についてお話し致します。

# やるべきこと！・考え方！

## ・設計書を見て何がわかり、何がわからないかを把握し考える！！！
当たり前ですが、「そもそも見たことないからわからないだろうで全部聞こう！」
はダメです。
なぜなら、自分で見て考えていかないとこれから先の成長度が違うからです。

この業界で仕事をするのであれば、考えることは一番大事だと思います。



## ・見て考えてわからないことはとにかく聞くこと
小学校とかであると思うのですが、
算数なんかで公式を

1.聞いて見ただけのなんとなく理解した人と

2.聞いて見てさらに理解できない部分を質問し理解する人

一目瞭然ですよね？
やはり、質問して自分の中にしっかり落とし込む人の方が応用に対しても躓きにくいです。
ただ、これをできる人が案外少ないんですよね。（私もそうでした（ ;  ; ））

あと、
とりあえず出された課題を自分なりに解釈してやってみる。
↑↑↑
これ、私もやってました。
現場でこんなことやると確実に怒られます。
仕事でプログラミングをする場合は、その行動に対してお金が発生します。
つまり、自分だけの時間では無くなります。
そんな中で、おそらくとかたぶんとかの理解で作業を始めてしまうと‥‥おわかりいただけただろうか？

そうですね。
皆さんが考えているように、余計なバグを発生させたり、そもそも作ってほしい物が全く違ったりとそんなことになってしまいチームの全員に迷惑をかける恐れが‥‥！

![2FA31C5D-5303-4C5B-BC2A-E7F432CFB374.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2701052/71da5c8e-c51c-baaf-161f-502e812e3f51.jpeg)



# 解決策として

もうこれは一つしかありません。
とにかくわからないやなぜなどの疑問をなくし、理解を共有することです。

相手も忙しいとピリピリしてることあると思いますが、とにかく心を無にして聞くことが重要です！
「こんなのもわからんのか⁉︎」「今忙しいの見てわからないかな⁉︎」など怒られてもとにかく聞くことです。
どんな罵声よりも、与えられた仕事をこなせなかい事やプログラムの質を落としてしまった結果で怒られるよりはマシです。

### とにかく聞く！

# 終わりに
これから私含め新しくこの業界に入って仕事をしていくと思うのですが、何度も言うように考えることをやめないでください。

今出来なくてもその時考えてわからない！！ってなった方が後々解決策を覚えている物です。

一緒に頑張りましょう！

なんか自分に言い聞かせるように書き綴ってしまいました笑

長々とありがとうございます(^^)

以上
Keycloakを利用した多要素認証（OTP認証）

# Keycloakを利用した多要素認証（OTP認証）

- Windows 10 Pro
- JDK 17(Eclipse pleiades 同梱のJDK17)
- Keycloak 20.0.3(2023/1/14時点最新)

## Windows対応版のKeycloakセットアップ

### Keycloakのダウンロード

keycloak本体を以下よりダウンロード
https://github.com/keycloak/keycloak/releases/download/20.0.3/keycloak-20.0.3.zip

Windows10のローカルドライブの下記フォルダへzipを展開
`C:\tools\keycloak\keycloak-20.0.3`

### Keycloakを起動する

JDKをインストールしていないため、Eclipse pleiadesに同梱されているJDK17を利用するように、keycloak起動用のbatファイルを修正し、JAVA_HOMEの設定を追加。

```bat:C:\tools\keycloak\keycloak-20.0.3\bin\kc.bat
@echo off
rem -------------------------------------------------------------------------
rem Keycloak Startup Script
rem -------------------------------------------------------------------------

rem 以下の設定を追加
set JAVA_HOME=C:\eclipse\pleiades-2022-06\java\17
set PATH=%JAVA_HOME%\bin;%PATH%
```

コマンドプロンプトを起動して以下のコマンドを実行しkeycloakを起動する。

```shell
C:\tools\keycloak\keycloak-20.0.3\bin\kc.bat start-dev
```

### Keycloak Admin Console利用のための初期設定

http://localhost:8080/
にアクセスしてAdmin ConsoleのユーザーをCreateする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/ea815f21-6cc9-2660-c0c8-903d38a89e27.png)

Admin Consoleにアクセスして、作成した管理者でログインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/129c6e1f-7f9b-b4e8-1d74-fe22d29085c4.png)

### OTP（One Time Password）認証のためのレルム作成

画面左上にあるコンボボックスを選択して`Create Realm`ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/da214ac0-0e74-42e0-3749-4bea59c5b9f6.png)

任意のレルム名を設定してCreateボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/d476ab2d-1b7f-f802-2c96-eabccd0f4006.png)

### OTP認証の設定

Authentication -> Flows -> Policiesタブ -> OTP Policy で任意の設定項目を変更する。
公式の[TOTP configuration options](https://www.keycloak.org/docs/latest/server_admin/#totp-configuration-options)を参考に設定を検討する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/725661a8-9d81-7a37-fb7d-4694757ce92d.png)

## Keycloakに動作検証用のユーザーを追加してOTP認証の動作確認

Create new user ボタンを押下
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/d8390f60-9ab3-f48a-dd38-e21f0506d5cf.png)

任意のユーザーを追加
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/c01994ea-be26-8a1e-6ebc-33f3c0c64a4c.png)

追加したユーザーの初期パスワードを設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/63970fe8-27fe-9345-fe39-74e301f84061.png)

以下にアクセスして、作成したユーザーでサインインする。
http://localhost:8080/realms/otp-sample/account

サインインするとこんな画面が出てきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/bae23524-a469-dfb5-afed-7eb3df4c66af.png)

Google Authenticatorが利用できるアプリの候補に出てきていないので、FreeOTPのツールをスマホにインストールして、QRコードを読み込みワンタイムパスワードを入力することで無事ログインできることを確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246556/5c0b40c4-65f1-8f7b-1abd-7de058813de4.png)
bundle install 時に ruby_dep-1.5.0 でエラーが出た際の対処法

## これはなに
アプリケーションの ruby のバージョンを３系に上げる際に発生した、`ruby_dep-1.5.0` エラーの対処法の備忘録です。

## 問題のエラー
ruby のバージョンを2系から３系に上げるために
`bundle install`を実行した際、以下のエラーが発生しました。

```
bundle install
Fetching gem metadata from https://rubygems.org/.........
Resolving dependencies...
ruby_dep-1.5.0 requires ruby version >= 2.2.5, ~> 2.2, which is incompatible with the current version, ruby 3.0.5p211
```

ruby_dep が必要としている ruby のバージョンに、３系が含まれていないことにより発生しているようです。

## 調査

### ruby_dep の依存関係を確認する

以下のコマンドで ruby_dep の依存関係を確認します。
```console
bundle update ruby_dep
```

以下が実行結果です。
```console
Bundler found conflicting requirements for the Ruby version:
  In Gemfile:
    Ruby (~> 3.0.5.0)

    listen (>= 3.0.5, < 3.2) was resolved to 3.1.5, which depends on
      ruby_dep (~> 1.2) was resolved to 1.2.0, which depends on
        Ruby (>= 2.2.3, ~> 2.2)
```

どうやら、listen と依存関係にあるようです。

### listen を update

まず依存関係にある listen を update します。

```
bundle update listen
```

以下が実行結果です。
```
Using listen 3.0.8 (was 3.1.5)
```

3.1.5 → 3.0.8 に更新されました。
Gemfile.lock を確認したところ、ruby_dep への依存関係が無くなったようです。

### 再度 bundle install を行う

listen が ruby_dep を必要としない状態にできたので、
再度 `bundle install` を試してみました。

結果、エラーは出なくなり、正常に `bundle install` を完了することができました。
「情熱プログラマー」を読んで印象に残った言葉

# イントロダクション
・「 就 職 し て 安定 した 楽 な 生活 を 送 りたいという 理由 でミュージシャンになる 奴 などいない。 音 楽 業 界 はそんなに 甘 いところではない。」


# 第1章　市場を選ぶ
・「君 は 大 きな 投 資 をしようとしている。 投 資 しようとしているのはお 金 ではなく、 君 の 時 間 ―――つまり 君 の 人生 だ。」

・「市場の不均衡をつけ」
・「 ソフトウェアの 開 発 に 必要 な 上 っ 面 を 理解 するだけでなく、 そ のビジネスの 分 野 で 一 目 置 かれる 存在 になるべきだ。」

・「ミュージシャンは、 一度 演奏 したというだけでは 楽 曲 を 自分 のレ パートリーには 加 えない。 レパートリーに 加 えるのは、 その 曲 をものにしたときだ。 ビジネスの 分 野 における 経 験 にも 同 じことが 当 てはまる。

・「伝 説 のジャズギタリスト、 Pat Metheny が 若 いミュージシャンたちにアドバイ スするときの 決 まり 文句。 「どんなバンドで 演 るときも、 一番 下手 なプレイヤーでい ろ」

・「機 会 を 与 えられるだって！ そんなの 僕 だってな かったよ！ 僕 は 学 ぶ 機 会 を 自分 でつかまえたんだ。」

・「万能 選 手 はめったにいない ... そこに 価 値 があるんだ」

・「ほかに 何 も 知 らないことが スペシャリストだって 勘 違 いしてるんじゃないか 」

・「あり 余 るほどの 教育 を 受 けながら 期待 はずれな 働 きしかできない 同僚 と、 僕 との 違 い。 それは 情 熱 だ。 熱 中 できるかどうか。 」


# 第2章　製品に投資にする
・「老子 に 「人 に 魚 を 与 えれば、 それは 一日 の 糧 となる。 しかし 魚 の 釣 り 方 を 教 えれ ば、 それは 一生 の 糧 となる」 とある。 なかなかの 名言 だ。 でも 老子 は、 魚 の 釣 り 方 を 教 わりたがらず、 明日 もう 一匹 魚 をくれとねだる 人 がいることを 忘 れていた。 教 育 は、 教 師 と 生 徒 の 両 方 がいて 初 めて 成 り 立 つものだ。」

・「ある 領 域 をさらに 深 いところまで 掘 り 下 げていくときに 役 立 つ 2 つの 質 問 があ る。 それは、 「その 仕 組 みはどうなっているか」 と 「そうなるのはなぜか」 だ。」

・「本当 の 意味 で 何 かを 習 得 しようと 思 ったら、 誰 かに 教 えてみることをお 勧 めする。」
・「僕 らは、 教 えることによって 学 ぶ。 」

・「重要 なのは、 どのような 練 習 が 自分 に 必要 か 見 極 めることと、 本 番 （実 務） では 練 習 しないことだ。 練 習 の ための 時 間 は 君 が 作 らないといけない。 これは 君 の 責 任 だ。」


# 第3章　実行に移す
・「僕 らは 価 値 を 生 み 出 すことで 報 酬 をもらってる。」

・「誰 の 手柄 になるのかを 本当 に 気 にしている 人 は、 自分 のキャリア （少 なくとも 今 の 会社 でのキャリア） の 鍵 を 握 っているのがマネージャだってことを 思 い 出 そう。」

・「退 屈 な 仕 事 を 完璧 にこなそうとしたらどうだい？」

・「退 屈 な 仕 事 を 同僚 との 競 争 に 変 えよう。」

・「代 わりの 人 なんて 存在 し 得 ないと 誰 もが 納 得 する 本当 に 無 比 のソフトウェア 開 発 者 は 一 握 りしかい ない 。」
・「逆 に 考 えれば、 取 り 替 えがきく 存在 を 目 指 すことは 敵 意 のない 関 係 を 作 り 出 すこ とにつながるはずだ。」

・「メンテナンスだって 自由 で 創 造 的 にやれる」
・「自分 のリファクタ リングの 切 れ 味 を 試 すには 良 い 機 会 だ。 そのシステムをどこまでエレガントにできるだろう？」

・「保守 担当者 は 自分 の 創 造 力 を 存 分 に 発 揮 できる。 そうとわかる 成果 を 出 すのも、 はたまたシステム 障 害 を 引 き 起 こすのも、 担当者 の 腕 次第 だ。」

・「こういうふうに、 測 定 値 で 結 果 を 確 認 し ながらパフォーマンスを 改善 していく 作 業 は、 病 み 付 きになる 可能性 がある。」

・「Martin は 週 40 時 間 労 働 を 「8 時 間 燃 焼」 に 言 い 換 えたんだ。 これは、 どう 頑 張 っても 8 時 間 以上 働 き 続 けるのは 無 理 なくらい 容 赦 なく 働 くべき、 という 考 え 方 だ。」

・「失 敗 こそ 成功 につなげる 絶 好 の 機 会」
・「企 業 がミスを 犯 したときに 顧 客 にどう 対 応 するかは、 顧 客 からの 熱 烈 な 支持 を 築 く （ぶち 壊 す） 決 定的 な 要 因 になる 可能性 がある。」

・「本当 にできないとき 臆 せずに 「でき ません」 と 言 える 強 さを 持 ったチームメンバーがいれば、 彼 らの 「できます」 という 言 葉 には 偽 りがないと 確 信 できる。」

・「向上 に 役 立 つ 行 動 のほうに 注目 しよう。 そうした 行 動 を 2 つ 挙 げろと 言 われたら、 僕 は 失 敗 と 模 倣 だと 答 える。」


# 第4章　マーケティング... スーツ族だけのものじゃない
・「リーダーの 職 務 は、 会社 にとって 価 値 が 最 大 になるようなチームを 作 ることだ。 組 織 の 誰 にどんな 仕 事 ができるのか 知 らずに リーダーの 職 務 を 果 たせるだろうか。」

・「自分 の 業 績 は 自分 のビジネスの 言 葉 で 売 り 込 め」


# 第5章　研鑽を怠らない
・「今終わった仕事じゃなく、今やっている仕事に集中せよ」

・「大 きくて 困 難 な 目 標 を 目 指 すときには、 毎 日 その 目 標 に 近 づけたかは 気 にせず、 その 目 標 へ 向 かっ て 昨日 より 努力 できたかを 考 えることが 大 切 だ。」
[SASS] !defaultフラグ について整理


今までスルーしてきましたが業務内でこれらに向き合う必要が出てきたので、自分用に整理してみました。

# !defaultとは

まずは公式ドキュメントから

> Normally when you assign a value to a variable, if that variable already had a value, its old value is overwritten.

普通に書いたら変数宣言が重複した場合、新しく宣言した値で古い値は上書きされる

>Sass provides the `!default` flag. This assigns a value to a variable _only if_ that variable isn’t defined or its value is [`null`](https://sass-lang.com/documentation/values/null). Otherwise, the existing value will be used.


!defaultフラグを付けることで、未定義か定義済みでも値がnullの場合に限り値を上書きすることが可能


簡単に動作確認してみました。

# 実例

## !defaultなし

変数用のファイルvariables.scssをimportしたのち、同じ変数に値を代入した場合


```scss: variable.scss
$base-color: blue;

```

```scss: main.scss
@import "variable";
$base-color: red;

.testStyle{
  background: $base-color;
}
```

検証用のHTMLを適当に作成
```HTML: index.html

<div style={styles}>
	<h1 className="testStyle">
    	Sass !default 検証
	</h1>
</div>
```
この時、背景は新しく宣言した赤になる。
![Pasted image 20230114155359.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113025/66255638-bd3b-3d8e-7130-c363940721ed.png)


## !defaultあり

importした後に!defaultをつけて変数宣言した場合


```scss: variable.scss

$base-color: blue;

```

```scss: main.js
@import "variable";

$base-color: red !default;

.testStyle{
  background: $base-color;
}
```

この時、背景はdefaultを付けて宣言した赤ではなく、最初に代入した青色になる。
![Pasted image 20230114155605.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113025/0f8483fe-2246-42b6-ef65-8f103a37c667.png)





色々見ていると、共通で適用するスタイル用変数を!defaultで宣言し、各画面毎に新しくスタイルを適用したい場合、変数をオーバーライドする　という感じ。

以下は、一例。


```scss: common-variables.scss

$base-color: blue !default;
$sub-color: yellow !default;

```

```scss: page1.js

$base-color: red ;
@import "common-variables";

.h1{
  background: $base-color;
}

.h2{
  background: $sub-color;
}

```

この時、上書きした変数のみ変更される。

![Pasted image 20230114162458.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3113025/b00fbb1c-e029-df1d-f47d-78117850b499.png)


# 参考

Saas公式: https://sass-lang.com/documentation/variables


役に立ったという人がいれば幸いです。
grep,cut,sedでtsvから特定の行を抜き出して配列っぽくする。

grep,cut,sedでtsvから特定の行を抜き出して配列にする。
server2*の3列目を抜き出す場合。


```
grep -r "server2" hogehoge.tsv \
| cut -f3 | sed -e "s/^\(.*\)$/\"\1\",/g" | sed -e "$ s/,$//i"
```
Macbook Proが，「バッテリーは充電停止中」の表示を出し続ける

# はじめに
朝，Macを起動したら何もケーブルを挿していないにも関わらず，バッテリーは充電停止中の表示になった．ケーブル挿しても充電できない．
インターネットで検索かけても同じような症状が見つからない...
ので，誰か同じような症状が出た方のために書こうと思うが，多分参考にならないんじゃないかと書きながら思った(ゴメンナサイ)．

# 結果
先に結果から言うと，CMSリセットで治った．やっぱりMacが不調になったらCMSリセットが一番なんやなぁ．

# 環境
<dl>
<dt>MacBook Pro 2018 15inch</dt>
<dd>CPU: Intel Core i7</dd>
<dd>OS: MacOS 12 (Monterey)</dd>
</dl>

# 症状の詳細と試したこと
起動後「バッテリーは充電停止中」の表示．電源に接続してもしなくても変わらず．充電始まらない．前日まで充電できていた．
ちなみに電源ケーブルはMacに直接挿した．
電源を接続していない状態でシステム情報を見てみる．診断は...合格．電源タブでバッテリー情報，充電中:いいえ，AC充電器の情報，接続済み:はい．え，なぜ...?お化け電源いる(・∇・)
ログはどれ読めばいいだろう...読んでも分からない().

### 試したこと1. 再起動
PCが不調になったらまずこれ．
...うん，何も変わらない.

### 試したこと2. 電源アダプタとケーブルを変えてみる
とにかく充電できなきゃバッテリー残量0%になって詰む．
幸いなことに，友達が120WのACアダプタを持っていたので使わせていただいた．
- 自分のApple純正ACアダプタと純正ケーブル
    充電できない．
- 友達の120W ACアダプタと自分の純正ケーブル
    充電できない．
- 友達の120W ACアダプタと友達のAnkerのケーブル
    充電できた．
- 自分の純正ACアダプタと友達のAnkerのケーブル
    充電できない．

もしやACアダプタとケーブルがダメになったのか?
とりあえず，友達からアダプタを借りる．
充電できるようになったけど，充電中の状態で電源ケーブル抜くと，表示が充電中で変わらない...( ﾟ∀ ﾟ)ﾊｯ！永久機関だ!
馬鹿なこと言ってないで治します().

### 試したこと3. バッテリー設定変更
調べると充電停止中の表示が出るのはこれがいるかららしい．実際どうなのか知らんが，できることは片っ端から試してみる．
バッテリーの設定で，バッテリー充電の最適化をoffにする．
変わらず．

### 試したこと4. PRAMリセット
まず，システム終了．
次に，option + command + P + Rの4つのキーを同時に押す．勝手に電源入るだろうけど気にせず，リンゴマークが消えるまで押しっぱなしにする．
結果変わらず．

### 試したこと5. CMSリセット
これ，キー押すタイミングがいまいち分からん...

まずシステム終了．
電源ボタン(Touch ID)を10秒くらい押しっぱなしにする．
数秒待ってから，電源を入れる．
何も変わらず．

じゃあ次
兎にも角にもシステム終了．
キーボード左側のcontrolとoptionキー，右側のshiftキーの3つのキーを同時に押す．7秒くらい．起動しても気にしない．
次に押し続けているこの3つのキーに，電源ボタンを追加した4つを押す．追加で7秒くらい．
そしたら押すのやめて，数秒待ってから，電源を入れる．

治った!(^^)

## 結論
こんな結論にしたくはないけど止む無し，分からん!以上．
個人論だけど，CatalinaからMacOSがおかしくなってるって感じてて，この辺から何か異物でも潜んでるのかな...

もし同じ症状が出た人いたらCMSリセットをまず行って，って言う記事だけどまずこれをするか...そもそもこんな変な症状出るなんてそうそうないと思う．
Python×Djangoプロジェクトの環境構築

# 1.作業ディレクトリに入る。
```bash
cd ~/gitspace
```

# 2.仮想環境の構築
```bash:~/gitspace
virtualenv <仮想環境名>
```
**仮想環境とは、プロジェクトごとにバージョンやライブラリが混在しないよう区分けするシステムみたいなもの。仮想環境Aでは最新バージョンのpython、仮想環境Bでは古いバージョンのpythonを使うイメージ。**

仮想環境に移動
```bash: ~/gitspace
cd <仮想環境名>
```

# 3.仮想環境に入る
```bash: ~/gitspace/<仮想環境名>
source Scripts/activate
```
**仮想環境にいるとターミナルのコマンド入力欄の下に`(<仮想環境名>)`という表示がある。**

# 4.Djangoをインストールする。
```bash: ~/gitspace/<仮想環境名>
pip install django
```

# 5.Djangoプロジェクトの作成
```bash: ~/gitspace/<仮想環境名>
django-admin startproject <プロジェクト名>
```
プロジェクトに移動
```bash: ~/gitspace/<仮想環境名>
cd <プロジェクト名>
```

# 6.アプリケーションの追加
```bash: ~/gitspace/<仮想環境名>/<プロジェクト名>
python manage.py startapp <アプリ名>
```

**Djangoの実装手順は機能ごとに分けられたアプリケーションにデータベース、バックエンド、ルーティング処理を書いていく。アプリケーションごとにstartappで作っていく。**

# 7.VScodeを開く。
```bash: ~/gitspace/<仮想環境名>/<プロジェクト名>
code .
```

# 8.settings.pyの設定
プロジェクトフォルダの`settings.py`のアプリケーション、言語、タイムゾーンの設定を変更。
```python: <プロジェクト名>/settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    '<アプリケーション名>',    #←←←startappで作ったアプリ追加
]

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

# 9.サーバー起動
```bash: ~/gitspace/<仮想環境名>/<プロジェクト名>
python manage.py runserver
```
ローカルサーバーにアクセスしてロケットの画面が出たら成功。

（pipのバージョンでエラー出たのでpipをアップデートしてからDjangoをインストールし直してからサーバー起動した）

# 10.Gitの設定
リモートリポジトリ作成
↓
git管理するコマンド。プロジェクトフォルダ内で`git init`
↓
リモートリポジトリを登録する。`git remote add origin <リモートリポジトリのURL>`
↓
addしてcommitしてpush

# 11.仮想環境を抜ける
```bash: ~/gitspace/<仮想環境名>
deactivate
```

# 12.仮想環境に入って作業再開
```bash: ~/gitspace/<仮想環境名>
source Scripts/activate
```
プロジェクトフォルダに移動
```bash: ~/gitspace/<仮想環境名>
cd <プロジェクト名>
```
VScode起動
```bash: ~/gitspace/<仮想環境名>/<プロジェクト名>
code .
```
bin/rspecとbundle exec rspecの違い

# はじめに
・初学者向け
・【RSpec】であれ？っと思った方向けです
久々に書きました。お久しぶりです
Qiita 環境がずっと使えなかったためです

## **環境**

- Windows 11 Home
- Ubuntu20.04
- Ruby 3.0.1
- Ruby on Rails 6.0.3
- psql (PostgreSQL) 12.12
- Bundler version 2.3.25
<HR>

<br>
<br>

## **bin/rspecとbundle exec rspecの違い**
■bin/rspec<br>
Rails アプリケーションのルートディレクトリ直下のbin/rspec ファイルを読み込みに行く

> bin/ を付けておけば、Spring経由で高速にコマンドが実行される
bundlerが、gemのバージョンや依存関係も正しく処理してくれる
筆者：Almonta
出典元：[Almonta Blog-【Rails】bin/rspec と bundle exec rspec の違い](https://almonta2021blog.com/bin-rspec-%E3%81%A8-bundle-exec-rspec-%E3%81%AE%E9%81%95%E3%81%84/#:~:text=%E8%AA%AC%E6%98%8E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,bin/rspec,-%E3%83%BB%E3%81%9D%E3%81%AERails%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)


```
$ bin/rspec
zsh: no such file or directory: bin/rspec
```

<br>
<br>
■bundle exec rspec<br>
Gemfile.lockに書かれているバージョンのgemが動く
bundle exec を付けることで意図しないバージョンが起動することを防ぐ（そのためrspecだけでできないこともない）
<br>
<br>

> bin/rspecでviewが更新されなかったのは、gemとの依存関係が逆に悪さをしているように考えられる。binによる高速処理はあきらめてbundle execで実行する
筆者：Almonta
出典元：[Almonta Blog-【Rails】bin/rspec と bundle exec rspec の違い](https://almonta2021blog.com/bin-rspec-%E3%81%A8-bundle-exec-rspec-%E3%81%AE%E9%81%95%E3%81%84/#:~:text=%E3%81%97%E3%81%A6%E3%81%8F%E3%82%8C%E3%82%8B-,bundle%20exec%20rspec,-%E3%83%BBGemfile.lock%E3%81%AB)

```
$ bundle exec rspec

タスク管理機能
  一覧表示機能
    一覧画面に遷移した場合
      作成済みのタスク一覧が表示される (FAILED - 1)

Failures:

  1) タスク管理機能 一覧表示機能 一覧画面に遷移した場合 作成済みのタスク一覧が表示される---
```


<br>
<br>



## 【参考サイト】
[【Rails】bin/rspec と bundle exec rspec の違い](https://almonta2021blog.com/bin-rspec-%E3%81%A8-bundle-exec-rspec-%E3%81%AE%E9%81%95%E3%81%84/#:~:text=%E8%AA%AC%E6%98%8E%E3%81%97%E3%81%BE%E3%81%99%E3%80%82-,bin/rspec,-%E3%83%BB%E3%81%9D%E3%81%AERails%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3)
[Linux・Ubuntu理解に役立ちそうなサイト](https://www.khstasaba.com/?p=718)日々、コレ勉強
Linux、ネットワーク、セキュリティ、プログラミングのコトを主に書いています。

## 【今後記事投稿予告-気乗りしたら】
先輩受講生方の日記また、質問をもとに私のエラー対処法と実行結果の共有を予定しております
- [エラー：Failed to find Chrome binary.]
- Failure/Error: raise BrowserNotFound, ‘Failed to find Chrome binary.’Webdrivers::BrowserNotFound:Failed to find Chrome binary.
- [System specのエラーに関して]

# おわりに
記事閲覧有難うございました！！
EC2のステータスがrunningになるまで待つshell関数

AWS ClientでEC2インスタンスを立ち上げてからEIPを振りたいけど、
そのまま順番にコマンドを並べてもEC2はまずpendingステータスで起動するので連携でこける。

なのでrunningになるまで待つ関数を用意。
リトライの最大カウント数なども追加して利用予定。

```
#!/bin/bash


wait_ec2pending() {

    echo "instance-id: "$instance_id
    while :
    do
        instance_status=$(aws ec2 describe-instance-status \
            --instance-ids $instance_id \
            --query 'InstanceStatuses[].InstanceState.Name' | jq -r .[0])

        if [ "$instance_status" = "running" ]; then
            echo "OK: instance status running"
            break;
        fi
        echo "waiting for instance status change..."
        sleep 3
    done
}


# set one instance-id
instance_id="<your-instance-id>"
wait_ec2pending

echo "next process"
ここから始めるWeb3開発学習【リンク集】

# まえがき
自分がWeb3周りの知識を学習していて参考になった情報をまとめてみました。
Ethereumに寄ってます。
学習は順不同でもいいと思いますが、ほかの知識の前提になっていそうなものを手前に持ってきています。
③以降は自分に合うものを選んでやる、でよいと思います。
また、ある程度の英語力と何かしらのプログラミング経験が必要です。

ほかにもこんなのあるよ！などあれば編集リクエストやコメントでぜひ教えてください。


# ①俯瞰してみる

#### PoL
https://pol.techtec.world/ja/curriculum

テキスト・問題がセットの形式で学習できるWEBサイト。
仮想通貨ってなんだ？ウォレットって？マイニングとは？のレベルから学習する場合に。

#### Web3 リサーチ

https://blockchain.bitflyer.com/pdf/web3Research2023.pdf

#### dApp Developer Road Map
https://github.com/thecryptoshed/eth-dapp-developer-roadmap

dApp開発者になるのに必要なスキルが何かをロードマップとして整理したもの

#### DeFi-Developer-Road-Map
https://github.com/OffcierCia/DeFi-Developer-Road-Map/blob/main/DeFiRoadMapNewSVG.svg

↑のDeFi版

# ②仕組みを知る
#### 日本語で読むビットコイン原論文
https://www.kk-kernel.co.jp/qgis/HALTAK/FEBupload/nakamotosatoshi-paper.pdf

#### イーサリアムとは？
https://ethereum.org/ja/what-is-ethereum/


# ③作ってみる

#### ブロックチェーンを作ることで学ぶ 
https://qiita.com/hidehiro98/items/841ece65d896aeaa8a2a

#### solidity
https://solidity-jp.readthedocs.io/ja/latest/index.html

#### Learning Solidity
https://github.com/willitscale/learning-solidity

#### イーサリアムの開発ドキュメント
https://ethereum.org/ja/developers/docs/

#### クリプトゾンビ
https://cryptozombies.io/jp/

#### ブロックチェーン開発の概要
https://learn.microsoft.com/ja-jp/training/paths/ethereum-blockchain-development/


# ④より実践的に作ってみる

#### ROAD TO WEB3

https://docs.alchemy.com/docs/how-to-develop-an-nft-smart-contract-erc721-with-alchemy

#### Remix
https://remix.ethereum.org/

#### Openzeppelin
https://www.openzeppelin.com/contracts

#### Ganache
https://trufflesuite.com/ganache/

#### Truffle
https://trufflesuite.com/
【SQL】COALESCEを使って複数カラムのNULLではない値で並び替えをおこなえる

## やりたいこと
以下のテーブルがあったとします。
### booksテーブル
※`price_a`と`price_b`は、どちらか一方のみに必ず数値が入っている

| title | price_a | price_b |
| ---- | ---- | ---- |
| 本01 | 200 | NULL |
| 本02 | NULL | 100 |
| 本03 | 300 | NULL |

このとき、**`price_a`か`price_b`の安い順で並び替えたい**という要望がありました。
（上記のテーブルの例だと、「本02, 本01、 本０３」の順になるのがゴール）

## COALESCEを使うと解決できる
結論としては、以下のように`COALESCE`を使うことでスッキリ書けます。

```sql:sql
SELECT * FROM books ORDER BY COALESCE(price_a, price_b) ASC;
```

`COALEASE`は、()のリストを左から順に評価し、NULLではない場合はその値を使い、NULLの場合は次の式を評価してくれます。
https://dev.mysql.com/doc/refman/5.6/ja/comparison-operators.html#function_coalesce

## IFNULLも使える

例えばMySQLであれば、`IFNULL`を使うこともできます。
https://dev.mysql.com/doc/refman/5.6/ja/control-flow-functions.html#function_ifnull
`COALEASE`は()内にいくつも評価対象を書くことができますが、
IFNULLでは`IFNULL(a, b)`のように、「aがNULLならb」というような書き方ができます。

```sql:sql
SELECT * FROM books ORDER BY IFNULL(price_a, price_b) ASC;
```

## うまくいかなかった方法: GREATEST、LEAST

最初は`GREATEST`YA`LEAST`を使い、`price_a`と`price_b`の最大・最小値をとることでいけないかな？と思ったのですが、実際の値とNULLではLEASTで評価するとNULLを返してしまうようで、期待する結果にはなりませんでした。

```sql:sql
SELECT * FROM books ORDER BY LEAST(price_a, price_b) ASC;
+-------+---------+---------+
| title | price_a | price_b |
+-------+---------+---------+
| 本01  |     200 |    NULL |
| 本02  |    NULL |     100 |
| 本03  |     300 |    NULL |
+-------+---------+---------+
SELECT * FROM books ORDER BY GREATEST(price_a, price_b) ASC;
+-------+---------+---------+
| title | price_a | price_b |
+-------+---------+---------+
| 本01  |     200 |    NULL |
| 本02  |    NULL |     100 |
| 本03  |     300 |    NULL |
+-------+---------+---------+
```

## さいごに
最初は以下のように無理やり書いていました。
```sql:sql
SELECT * FROM books CASE WHEN price_a IS NULL THEN price_b ELSE price_a END ASC;
```
もっとすっきり書く方法がきっとあるはず、、、と思って社内で質問したところ上記の知見が得られたので良かったです。
Gitでコンフリクトを誤って解決してしまい、pushした際の解決法


## はじめに

現職で同僚がステージング環境の１つ前の環境にマージして、コンフリクトが発生しました。そのコンフリクトの解消に誤りがあったものの、気づかずにpushしてしまい、CircleCIで異常終了してしまったことで、コンフリクトの解消法に誤りがあったことが発覚しました。その際にどのように解決したら良かったのかを考えてみました。


## 解決策の候補

私が思いついた方法は以下3つでした。1つずつ方法を検証していきます。
- `git revert -m 1 <commitID>`
- `git reset --soft <commitID>`を実行後に`git push -f`
- マージ先のプログラムを直接修正

## `git revert -m 1 <commitID>`

この解決策の特徴は以下です。

- マージを取り消したことがログとして残ります。

- マージを取り消した後に、同じリポジトリを再度マージしてもマージを取り消したプログラムは反映されません。

今回のケースですと、コンフリクトの解消が誤っていたため、再度同じプログラムをマージ先に反映できないと困るため、今回の対応策としては適していないのかと思いました。



## `git reset --soft <commitID>`を実行後に`git push -f`

この解決策の特徴は以下です。

- マージを取り消した後に、同じリポジトリを再度マージしてもマージを取り消したプログラムは反映されます。

- マージを取り消したことはログには残りません。

- pushする際には強制pushしなければいけないため、他の開発メンバーの作業に影響を与える可能性があることです。[開発ブログ](https://www-creators.com/archives/5168)によると、強制pushの注意点として以下のように記載されております。

>強制 push は、自分ひとりで作業しているブランチでは、それほど問題にならないでしょう。一方で、チームで開発を行っているとき、共有されたブランチを強制更新するときは注意が必要です。
もし上書きにより、消されてしまったコミットを起点にして、チームメンバーがローカルで開発を進めていたとすると、そのようなメンバーが次回の push で必ず競合が発生してしまうだけでなく、すでに存在しない状態をベースに機能開発を進めてしまうため、すべての前提が崩れてしまう可能性さえあります。
チームメンバーが多いほど、このような問題は発生しやすいのではないでしょうか。共有されたブランチはできるだけ、強制上書きは避けるべきでしょう。


- マージを取り消して、再度マージするため、作業時間が「マージ先のプログラムを直接修正」よりもかかってしまうと思います。

今回のケースですと、マージを取り消して再度マージすることは可能性ですが、強制pushをしなければいけないため、他のメンバーへの作業影響を考えるとリスクが高いため、適していないのかと思いました。


## マージ先のプログラムを直接修正後に`git push`

この解決策の特徴は以下です。

- 修正したことがログに残ります。

- 強制push(`git push -f`)をしなくてもリモートブランチに反映できるため、他メンバーの作業に影響を与えません。

- マージを取り消して、再度マージする必要がないため、作業時間が`git reset`よりも短いと思われます。

今回のケースですと`git revert`と`git reset`よりも適した方法なのかと思いました。


## 最後に

今回記事を書いてみることで、コマンドそれぞれの特徴について理解を深められました。今回自分が考えた方法よりも良い方法をご存知の方がいらっしゃったら、コメントいただけますと幸いです。

## 参考文献

なおこの記事は以下の情報を参考にして執筆しました。

- [【git】マージしたけどやっぱりやめたい時のやり方4種類](https://qiita.com/chihiro/items/5dd671aa6f1c332986a7)
- [開発ブログ](https://www-creators.com/archives/5168)
確率母関数の積と独立

# 概要
独立な確率変数$X_1,X_2$があったとする（離散値）。

まず、確率母関数$G(s)$は次のように定義する。

```math
G(s) = E[s^X]
```

ここで新たな確率変数$Y$を次のように定義する

```math
Y = X_1 + X_2
```

確率変数が**独立な場合**、$X_1$と$X_2$の確率母関数の積は$Y$の確率母関数に一致する。

```math
G_{Y}(s) = G_{X_1}(s) G_{X_2}(s)
```
これを証明したい。

# 一般的な証明

```math
\begin{eqnarray}
G_Y(s) &=& E[s^Y]\\
&=& E[s^{X_1+X_2}]\\
&=& E[s^{X_1} s^{X_2}]\\
&=&E[s^{X_1}] E[s^{X_2}]\\
&=& G_{X_1}(s) G_{X_2}(s)

\end{eqnarray}
```
3行目から4行目は独立である条件より

```math
P(X_1 = x_1,X_2=x_2) = P(X_1 = x_1)  P(X_2 = x_2) 
```
といえることを利用した。より詳細に書くと

```math
\begin{eqnarray}
E[s^{X_1} s^{X_2}]&=& \sum_{(x_1,x_2)} s^{X_1} s^{X_2}P(X_1 = x_1,X_2=x_2) \\
&=&\sum_{(x_1,x_2)} s^{X_1} s^{X_2}P(X_1 = x_1)P(X_2=x_2) \\
&=&\sum_{(x_1,x_2)} s^{X_1}P(X_1 = x_1) s^{X_2}P(X_2=x_2) \\
&=&\sum_{x_1} s^{X_1}P(X_1 = x_1) \sum_{x_2}s^{X_2}P(X_2=x_2) \\
&=&E[s^{X_1}] E[s^{X_2}]\\
\end{eqnarray}
```

最後の行の式転換、$\sum$同士の積への変換、が少し気に食わない点以外は理解できた。

確率変数$Y$の母関数なのに$x$しか使わないのも気になるので別の方法で考えてみる。


# 確率変数の和
$Y$の確率は畳み込み計算になる。

例えば$Y=5$をとるのは

```math
(X_1,X_2) = (0,5),(1,4),(2,3),(3,2),(4,1),(5,0)
```
のように複数の場合の和になる。

```math
\begin{eqnarray}
P(Y=y) &=& \sum_x P(X_1 = x,X_2= y-x)\\
&=&\sum_{x=0}^{y} P(X_1 = x)P(X_2= y-x)
\end{eqnarray}
```
このような演算は畳み込み計算と呼ばれる。

# 別の証明

```math
\begin{eqnarray}
E[s^Y] &=& \sum_{y=0}^{D_Y} s^y P(Y=y)\\
&=& \sum_{y=0}^{D_Y} s^y (\sum_{x=0}^{y} P(X_1 = x)P(X_2= y-x) )\\
&=& \sum_{y=0}^{D_Y} (\sum_{x=0}^{y} s^x P(X_1 = x) s^{y-x}P(X_2= y-x) ) \\
\end{eqnarray}
```

ここで、

```math
\begin{eqnarray}
a(k) &=& s^k P(X_1 = k) \\
b(k) &=& s^k P(X_2 = k) \\
\end{eqnarray}
```
と置く。

先ほどの式を展開する。

```math
\begin{eqnarray}
E[s^Y] 
&=& \sum_{y=0}^{D_Y} \sum_{x=0}^{y} a(x) b(y-x ) \\
&=& a(0)b(0)  \\
& & +\{ a(0)b(1) + a(1)b(0) \} \\
& & +\{ a(0)b(2) + a(1)b(1) +a(2)b(0) \} \\
& & \vdots \\
& &  + \{a(0)b(D_y-1)+ \cdots + a(D_y -2)b(1) + a(D_y -1)b(0)  \}\\
& & + \{a(0)b(D_y)+ \cdots +a(D_y-1)b(1) +a(D_y)b(0) \} \\
&=& a(0) \{ b(0) +  b(1) +b(2) + \cdots + b(D_y)\}\\
& & +a(1) \{ b(0) +  b(1) +b(2) + \cdots + b(D_y-1)\}\\
& & +a(2) \{ b(0) +  b(1) +b(2) + \cdots + b(D_y-2)\}\\
& & \vdots\\
& & +a(D_y -1 )  \{ b(0) +  b(1)\} \\
& & +a(D_y) \{b(0) \} \\

\end{eqnarray}
```
ここで、$Y$の取り得る範囲$D_y$を$\infty$にする。


```math
\begin{eqnarray}
E[s^Y] 
&=& \sum_{y=0}^{D_Y} \sum_{x=0}^{y} a(x) b(y-x ) \\

&=& a(0) \{ b(0) +  b(1) +b(2) + \cdots　\}\\
& & +a(1) \{ b(0) +  b(1) +b(2) + \cdots \}\\
& & +a(2) \{ b(0) +  b(1) +b(2) + \cdots \}\\
& & \vdots\\

&=& \{a(0) + a(1) + \cdots \} \{ b(0) +  b(1) +b(2) + \cdots \}\\
&=& \sum_{x=0}^{\infty} s^k P(X_1 = x) \sum_{x=0}^{\infty} s^k P(X_2 = x)\\
&=& G_{X_1}(s) G_{X_2} (s)
\end{eqnarray}
```
となって確率母関数の積となった。

結局、一般の証明と同じで、$\sum$同士の積にするためには取り得る範囲を無限大にする必要があった。
そんなことないのか？？？？
（追記：範囲を無限大にするというより、$(x_1,y)$の取り得る範囲と$(x_1,x_2)$の取り得る範囲を$x_1 + x_2 = y$で関係づけているという考えの方がいい。その範囲内での総和は一致するということを今後証明してみたい）



# まとめ
+ 独立変数の和の確率母関数は、元の確率母関数同士の積になることを示すことができた。
+ 今回は離散値に関して示したが、できれば連続値の場合も示したい。
+ 取り得る範囲を無限大にしないと一致しないように見える。そんなことない気がするのだけど、どうなんだろうか。

https://qiita.com/utaka233/items/1937bfcb3d1cbae0e8df

も面白い。
SpringBootで@Validatedでバリデーションチェックが行われない

# はじめに

ToDoリスト用の簡単なAPIを作成する際にToDoのタイトルのバリデーションチェックをしようとしました。タイトルが未入力の場合500エラーを返そうとして、`@Validated`というものを利用したのですが、なぜかうまく動かずかなり苦戦したのでまとめます

# 問題

以下のAPIを作成しました

```kotlin:ToDoController.kt
package com.example.todolist

import com.example.todolist.application.service.ToDoService
import com.example.todolist.domain.model.ToDo
import com.example.todolist.presentation.form.GetTodoListResponse
import com.example.todolist.presentation.form.RegisterToDoRequest
import com.example.todolist.presentation.form.ToDoInfo
import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.validation.BindingResult
import org.springframework.validation.annotation.Validated
import org.springframework.web.bind.annotation.*
import javax.management.BadAttributeValueExpException

private val logger = LoggerFactory.getLogger(ToDoController::class.java)

@RestController
class ToDoController(
    private val toDoService: ToDoService
) {
    @PostMapping("/todo")
    @ResponseStatus(HttpStatus.OK)
    fun createToDo(@RequestBody @Validated request: RegisterToDoRequest, bindingResult: BindingResult) {
        if (bindingResult.hasErrors()) {
            throw BadAttributeValueExpException("タイトルを入力してください")
        }
        toDoService.register(
            ToDo(
                0,
                request.title,
                false,
            )
        )
    }
}
```

```kotlin:ToDoForm.kt
import javax.validation.constraints.NotBlank
data class RegisterToDoRequest(
    @field:NotBlank
    val title: String,
)
```

```kotlin:build.gradle.kt
	implementation("org.springframework.boot:spring-boot-starter-validation")
	implementation("javax.validation:validation-api:2.0.1.Final")
```

`javax.validation`はいろいろ記事を探していて、このアノテーションを利用すると書いてあるものが多かったので入れています

しかし、このAPIを叩いても何故かバリデーションチェックは行われず`bindingResult`のエラーは`0`となってしまいました

# 解決方法

`@NotBlank`を`javax.validation.constraints.NotBlank`から利用していましたが、`org.hibernate.validator.constraints.NotBlank`を利用することでバリデーションが動くようになりました

```kotlin:ToDoForm.kt
package com.example.todolist.presentation.form

import com.example.todolist.domain.model.ToDo
import org.hibernate.validator.constraints.NotBlank

data class RegisterToDoRequest(
    @field:NotBlank
    val title: String,
)
```

依存関係に追加していた

```kotlin:build.gradle.kt
implementation("javax.validation:validation-api:2.0.1.Final")
```

は削除しました

# おわりに

かなり調べて試行錯誤してうまくいかなかったのでここまでたどり着くのに時間がかかりました
同じような減少が起きる人はおそらくいるのではないかと思いますので、役立てばうれしいｄ
新卒SEバブルソート書いてみた

基本情報技術者の擬似言語の学習のため実際にプログラム化してみました。
基本情報の問題集をもとにフローチャートを作成し、コーディングをおこなっております。


```java:Qiita.java
import java.util.*;

public class BubbleSort {
  
  public static void main(String[] args){

    try {
      Scanner sc = new Scanner(System.in);
      System.out.println("作りたい配列の要素数を入力してください");
      int size = Integer.parseInt(sc.next()); 
      int[] data_array = new int[size]; 


      /*
       * テストデータ
       * 要素数 8
       * 47,33,68,55,74,89,25,10
       * 3,5,8,4,0,6,9,1
       * 7,7,7,7,7,6,9,1
       * 0,0,0,0,0,0,0,0
       * 80,70,60,50,40,30,20,10
       * 70,60,40,70,30,70,50,70
       * 80,60,40,70,30,10,50,20
       * 80,60,40,70,30,10,50,20
       * 80,60,40,70,30,10,50,70
       * 
       *
       */


      System.out.println("配列要素数が" + size + "個になるよう各要素に格納する値を入力してください 降順で並び替えます");
      for (int i = 0; i < size; i++) {
        data_array[i] = Integer.parseInt(sc.next());
      }

      System.out.println("配列入力結果→" + Arrays.toString(data_array));



      int swap_count = bubbleSort(data_array);//バブルソート
      printResult(data_array, swap_count); //結果出力

    } catch (Exception e) {
      System.out.println("エラー;" + e.getMessage());// エラーメッセージ表示
      e.printStackTrace(); // スタックトレース

    }
  }

  public static int bubbleSort(int[] data_array){
    int swap_count = 0;
    int tmp = 0;

    for(int i = 0; i < data_array.length - 1; i++){
      for(int j = i + 1; j < data_array.length; j++){

        //入れ替え
        if(data_array[i] < data_array[j]){
          tmp = data_array[i];
          data_array[i] = data_array[j];
          data_array[j] = tmp;
          swap_count++;
        }
      }
    }

    return swap_count;
  }



  public static void printResult(int[] data_array, int swap_count){
    System.out.println("バブルソート結果");
    System.out.println(Arrays.toString(data_array));
    System.out.println("交換回数は"+ swap_count + "回です。");
  }
  
}
【Minecraft】古い公式ランチャーを今でも使いたい

…という奇特な人がいるかはさておき。発見したので書き残しておく。

Linuxなら次のコマンドでできる (要`jq`)。
```bash
JAR_URL="$(curl https://launchermeta.mojang.com/v1/products/launcher/6f083b80d5e6fabbc4236f81d0d8f8a350c665a9/linux.json \
  | jq -r ".java_launcher")"

curl --output legacy-launcher.jar "$JAR_URL"
```

インストールが終わった後は
```
java -jar ./legacy-launcher.jar
```

注意点として、Microsoftアカウントでのログインに対応していないのでそんなに使う価値はないと思われる。
Javaでタイムスタンプリクエストを作成する

Javaの標準ライブラリにはタイムスタンプリクエストを生成するクラスは存在しないので、今回は[Bouncy Castle Crypto APIs](https://www.bouncycastle.org/java.html)を使用してタイムスタンプリクエストを生成します。

## Bouncy Castle Crypto APIs のダウンロード

[LATEST JAVA RELEASES](https://www.bouncycastle.org/latest_releases.html)から最新版をダウンロードします。

タイムスタンプリクエストを作成するために必要なjarファイルは、Provider, ASN.1 Utility Classes, PKIX/CMS/EAC/PKCS
OCSP/TSP/OPENSSL の jar ファイルになります。

Javaでタイムスタンプリクエストを作成するには、[org.bouncycastle.tsp.TimeStampRequestGenerator](https://www.bouncycastle.org/docs/pkixdocs1.8on/org/bouncycastle/tsp/TimeStampRequestGenerator.html)を利用します。

```java
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import org.bouncycastle.tsp.TSPAlgorithms;
import org.bouncycastle.tsp.TimeStampRequest;
import org.bouncycastle.tsp.TimeStampRequestGenerator;

public class HelloWorld_TimeStampReq {

	public static void main(String[] args) {

		//ハッシュ値の生成 SHA-256
		try {
			MessageDigest sha256 = MessageDigest.getInstance("SHA-256");
			byte[] sha256Byte = sha256.digest("Hello World".getBytes());
		
			TimeStampRequestGenerator reqGen = new TimeStampRequestGenerator();
			reqGen.setCertReq(true);
			TimeStampRequest req = reqGen.generate(TSPAlgorithms.SHA256, sha256Byte);
			
			FileOutputStream fos = new FileOutputStream("HelloWorld.req");
			fos.write(req.getEncoded());
			fos.close();
			
		}
		catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} 
		catch (IOException e) {
			e.printStackTrace();
		}
		catch (Throwable e) {
			e.printStackTrace();
		}
	}

}
```
SwiftのArrayを特定の要素で区切ってグループ化したいときにchunkedが使えた

# 実行環境
Xcode14.1

# 前置き
https://github.com/apple/swift-algorithms

swift-algorithmsを利用してうまくリファクタリングできたので紹介したい。
この中のchunkedを使用した。

どのような機能かはこちらがわかりやすかった。
https://qiita.com/jollyjoester/items/4e5df18e4f5c0429ee9e#chunked

> Chunkは「かたまり」のことです。
> コレクションを複数のサブシーケンスに分割します。


# やりたいこと
SwiftのArrayを特定の要素で区切りたいことがあった。
具体的なケースとして、NaturalLanguage Frameworkの利用時に発生した例を示す。
NaturalLanguage Frameworkで文字列を解析したときに、文字列を記号や単語などにタグ付してくれる。この中の単語の部分を記号で区切りたかった。

具体例のコードを示す。
文字列を解析するコード
```swift
import NaturalLanguage

typealias TextTag = (text: String, tag: NLTag)
func makeTagByNL(text: String) -> [TextTag] {
    let tagger = NLTagger(tagSchemes: [.lexicalClass])
    tagger.string = text
    let options: NLTagger.Options = [.joinNames, .omitWhitespace]
    
    var array = [(String, NLTag)]()
    tagger.enumerateTags(in: text.startIndex..<text.endIndex, unit: .word, scheme: .lexicalClass, options: options) { tag, tokenRange in
        if let tag = tag {
            array.append((String(text[tokenRange]), tag))
        }
        return true
    }
    return array
}
```

利用例
```swift
let text = "野菜（じゃがいも（国産）、にんじん、とうもろこし）、トマトペースト"
let service = LinguisticService()
let result = service.makeTagByNL(text: text)
```

下記のようなデータが得られた。
```
text: 野菜, tag: OtherWord
text: （, tag: Punctuation
text: じゃがいも, tag: OtherWord
text: （, tag: Punctuation
text: 国産, tag: OtherWord
text: ）、, tag: Punctuation
text: に, tag: OtherWord
text: ん, tag: OtherWord
text: じん, tag: OtherWord
text: 、, tag: Punctuation
text: とうもろこし, tag: OtherWord
text: ）、, tag: Punctuation
text: トマト, tag: OtherWord
text: ペースト, tag: OtherWord
```

ここから記号を除去したいのだが、問題として野菜、じゃがいもなどはいいが、にんじんは文字列がバラバラになってしまっていた。バラバラな文字列は結合したい。そこで、結合のために単語を記号ごとにグループ化しようとした。

```swift
// 欲しいデータ
["野菜", "じゃがいも", "国産", "にんじん", "とうもろこし", "トマトペースト"]
```

# 実装
## chunkedを使わない、リファクタリング前のコード。
事前にグループ化用のArray(oneWordArray)を用意して、記号が来たら保存用のArray(oneWordResult)に追加していった。 `oneWordArray.reduce("") { $0 + $1 }` で結合を行った。
```swift
func ommitPunctuation(array: [TextTag]) -> [String] {
    var oneWordArray = [String]()
    var oneWordResult = [String]()
    for wordAndTag in array {
        if wordAndTag.1 == NLTag.punctuation {
           if oneWordArray.count > 0 {
               let reduced = oneWordArray.reduce("") { $0 + $1 }
               oneWordResult.append(reduced)
               oneWordArray.removeAll()
           }
           continue
        }

        oneWordArray.append(wordAndTag.0)
    }
    if !oneWordArray.isEmpty {
        let reduced = oneWordArray.reduce("") { $0 + $1 }
        oneWordResult.append(reduced)
    }

    return oneWordResult
}
```

## chunkedを使うリファクタリング後のコード
chunkedでtagが異なる場合に別のグループとするように指定した。
fileterで単語のみにした。
mapでグループごとに結合を行った。
```swift
func ommitPunctuation(array: [TextTag]) -> [String] {
    return array.chunked(by: {
        $0.tag == $1.tag
    }).filter {
        $0.first?.tag == .otherWord
    }.map {
        $0.reduce("") { $0 + $1.text }
    }
}
```

chunkedを使うことで見通しの良いコードを書くことができた。
Windows11上でflutter環境構築をする時に発生したエラー"Unable to find bundled Java version"を解決する。

flutterの環境構築時に"Unable to find bundled Java version"というエラーが発生した。
解決方法を検索しても、windows環境下での解決方法がなかなか見つけられなかったので、備忘録として記す。

## 環境
OS: windows11
CPU: intel Corei7 12700H

## 状況
flutter doctorコマンド入力時に、"Unable to find bundled Java version"というエラーが発生する。

## 解決方法
解決方法は、非常に簡単だった。
GitHubアカウント名、mstfkhazaalという方が非常に有益な情報をGitHubで発信してくださっていた。
![ABC.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052981/bbfe0016-97f0-e0b1-069f-7946ec07b314.png)
日本語訳(google翻訳)
![あいう.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3052981/cea192e9-f239-85c0-00a2-999dbd20f928.png)

## ソース元
https://github.com/flutter/flutter/issues/106674
コピペで出来るDjangoアプリケーション開発環境構築（その２）

# はじめに

https://www.udemy.com/share/103OHY3@Hp1LP8z4636rKvwf7s6WkJUqqjnfnoWk1ugFKS8PxdYwWkOnNH9OsoDQnZhF7KisUg==/

この講座を見てDjangoの勉強をしています。
今後の開発のために簡潔に開発の流れをまとめました。
その２です

[その１](https://qiita.com/scythercas/items/e96b70aeab4698065dfb)

# 開発環境構築の流れ（続き）

## アプリケーションを作成する（前記事にも書いてあります）

```terminal
$ python manage.py startapp sample_app
```

## `sample_project`フォルダ内の`settings.py`を修正する
40行目ぐらい
```diff_python
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
+   "sample_app",
]
```
`sample_app`がアプリケーションとして読み込まれるようにする記述。

## `sample_project`フォルダ内の`urls.py`を修正する
```diff_python
- from django.urls import path
+ from django.urls import path, include

urlpatterns = [
    path("admin/", admin.site.urls),
+   path("sample_app/", include("sample_app.urls")),
]
```
`http://127.0.0.1:8000/`の次が`sample_app`なら、`sample_app`フォルダ内の`urls`ファイルを読み込むようにする記述。

## `sample_app`に`urls.py`ファイルを新規作成する
```py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```
urlの`sample_app/`の次が`''(何もなし)`または`index`ならば、`views`ファイルの`index`関数を読み込むようにする記述。

## `sample_app`フォルダ内の`views.py`を修正する

```diff_python
from django.shortcuts import render
+ from django.http import HttpResponse
# Create your views here.
+ def index(request):
+    return HttpResponse(f'<h1>Hello</h1>')
```
関数が読み込まれたときに`<h1>hello</h1>`と返すようにする記述

## 実行確認
```terminal
$ python manage.py runserver
```
urlの末尾に`sample_app`と追加して実行。Helloと表示されればおｋ

## htmlファイルを返す場合

### 新規アプリケーションフォルダを作成する
```terminal
$ python manage.py startapp sample_appapp
```
`sample_appapp`フォルダとする

### `sample_project`内の`settings.py`を修正する

40行目くらい
```diff_python
INSTALLED_APPS = [
    "django.contrib.admin",
    "django.contrib.auth",
    "django.contrib.contenttypes",
    "django.contrib.sessions",
    "django.contrib.messages",
    "django.contrib.staticfiles",
    "sample_app",
+   "sample_appapp",
]
```

### `sample_appapp`フォルダ直下に`templates`フォルダを作成する
`templates`という名前じゃないとだめです

### `templates`フォルダの直下に`appapp`フォルダを作成、さらにその直下に`index.html`を作成する

```index.html
<h1>読み込めた</h1>
```

### `sample_app`内の`views.py`を修正する

```diff_python
from django.shortcuts import render
from django.http import HttpResponse

def index(request):
-   return HttpResponse(f'<h1>hello</h1>')
+   return render(request, 'appapp/index.html')
```
自動で`templates`フォルダを認識して読み込んでくれるので、`templates`の指定は不要。
これで`index`関数が実行されたときにHTMLファイルを返すようになった。

### 実行確認
```terminal
$ python manage.py runserver
```
urlの末尾に`sample_app`と追加して実行。「読み込めた」と表示されればおｋ

## 続き

https://qiita.com/scythercas/items/a55548db6dd4e8edc59b
『debian linux』でサーバーのシステム時間とハードウェアクロックの時間を暫定的にセットする。（２）

　

# 目的
    止む得ない場合に時間を設定するために近隣のwwwサーバやポートが開いている外部のwebサーバから取得し設定する。
    ※以前記載したものをperlを使用しない方法を検討した。

# 方法
システム標準ツールのみで動作する。
http,httpsの通信で取得する。
使用するツール
bash
wget
date
hwclock
※debianlinux10では標準に入っている。

# code 
```
#!/usr/bin/env bash
URL_S=http://www.google.com
DATE_S=`/usr/bin/wget -o - -S --spider ${URL_S} 2>/dev/null | grep 'Date:'| sed -e 's/^ *Date: //'`
DATE_E=' -s "'${DATE_S}'"'
echo date ${DATE_E}
date -s "${DATE_S}"

DATE_S=`date -d "${DATE_S}" +'%d %b %Y %H:%M:%S'`
HWCLOCK_E=' --set --date "'${DATE_S}'"';
echo hwclock ${HWCLOCK_E}
hwclock --set --date "${DATE_S}"
```

# 反省
以前の記事ではdateやhwclockなどのコマンドの理解が足りなかったので、
改めてマニュアルを確認して動作検証を行った。
検証した機械ではbusyboxのwgetが--spiderオプションがなかったため、使用できなかった。
アダルト画像を完全無料で検出するAPI

# 前置き
アダルト画像を検出するAPIは大抵リクエスト数に制限があり、完全に利用するのは難しいですよね。
そこでGitHubを漁っていたら完全無料で検出を行えるAPIを見つけたので紹介していきたいと思います。
注意ですがローカルの画像は検出できません。URL形式の画像リンクのみ検出可能です。

## API説明
【API名】
　nsfw_api

【簡単な概要】
[Caffe](https://github.com/BVLC/caffe)用のモデルを提供する[open_nsfw](https://github.com/yahoo/open_nsfw)に依存した、画像がアダルトコンテンツを含むか予測するREST APIである。
質を向上させることを目的とせず、無料で必要とする多くの人に提供することを目標としている。

## API導入方法

### 事前準備

【Dockerダウンロード】
dockerをダウンロード、インストールする必要があります。(※インストール済みの場合は次へ)
ここでダウンロード方法については割愛しますが、下記のサイトで丁寧に説明されています。
https://sukkiri.jp/technologies/virtualizers/docker/docker-win_install.html
　

【WindowsユーザーはPC電源オプションを変更】
DockerではPCの電源オプションの設定によっては、不具合が生じる場合があるので、事前に設定を変更しておきましょう。
変更箇所は「高速スタートアップ」に関する箇所ですが、記事の趣旨とずれてしまうので下記サイトを参考にしてみてください。
https://mameco0127.hatenablog.com/entry/2020/12/09/184030

### Docker起動
Dockerを起動しておきましょう。
またまたWindowsユーザーですが、起動後に「Docker Desktop starting...」が表示されたまま変化のない場合は下記の記事を参考に解決してみてください。
https://qiita.com/azumi_/items/c544f9b44e1cdb8c6fe0

### コンテナを生成
コマンドプロンプト上で下記のように入力し、コンテナを生成します。
```:cmd
>>docker run -it -p 127.0.0.1:5000:5000/tcp --env PORT=5000 eugencepoi/nsfw_api:latest
```
いくらたっても完了しない場合は、新たに別のコマンドプロンプトを開き、
```:別のcmdにて
>>docker ps
```
と入力してみてください。

```:結果1
>>docker ps
CONTAINER ID   IMAGE                       COMMAND                
〇〇〇   　　　 eugencepoi/nsfw_api:latest  "/bin/sh -c 'gunicor…" ...省略
```
```:結果2
>>docker ps
CONTAINER ID    IMAGE    COMMAND    CREATED    STATUS    PORTS    NAMES
```
【結果1の場合】
結果内に「eugencepoi/nsfw_api:latest」というイメージが入っていれば生成は完了しているので、全てのコマンドプロンプトは閉じてOKです！
【結果2の場合】
結果内に列名のみが出力された場合は、まだ生成を完了していないか、エラーが発生している可能性が高いです。
 
 
## 検出実行
①適当なブラウザを開いてください。
②アドレスバーに下記の様に入力してください。
```:アドレスバー
http://localhost:5000/?url=〇〇〇
```
「〇〇〇」の部分は画像のURLを入れてください。
前置きでも説明した通り、〇〇〇の部分は画像リンクのみ対応しています。
そしてEnterしてアクセスすると...

```:結果
{"score":0.052383366972208023,"url":"〇〇〇"}
```

このような結果が表示されます。
scoreの部分が判定結果になり、「0 ～ 1」の間の数値が返ってきます。
返ってきた数値が0に近ければアダルト画像である可能性は低く、1に近ければアダルト画像である可能性が高いという判定です。



## 参考
下記のリンク先が今回紹介したAPIのGithubリポジトリです。
https://github.com/EugenCepoi/nsfw_api
linux コマンド ユーザー一覧とユーザーグループ一覧を出力するコマンド

## 概要

- linuxにてユーザー一覧とユーザーグループ一覧を出力するコマンドを簡単にまとめる。

## ユーザー一覧を出力するコマンド

```shell
cat /etc/passwd | cut -d : -f 1
```

## ユーザーグループ一覧を出力するコマンド

```shell
cat /etc/group | cut -d : -f 1
```

## 簡単な解説

- `/etc/passwd`もしくは`/etc/group`のファイルの内容を呼び出し、`:`で区切った`1`フィールド目をターミナル上に出力している。
- 区切り文字は`-d`オプションで設定する
- フィールドは`-f`オプションで設定する
【SQL Server】「ユーザー はログインできませんでした。 理由: このアカウントのパスワードを変更する必要があります。」の対応

# はじめに
社内サーバーの Windows OS + SQL Server バージョアップ作業にともない、SQL Serverに接続していたアプリケーション(Classic ASP)を動かすと「ユーザー はログインできませんでした。 理由: このアカウントのパスワードを変更する必要があります。」のエラーにより動作しない。

原因は分かってしまえば簡単なことだったんですが、それに気が付くまでに数時間かかってしまったので備忘録として記事にします。

# 原因
パスワードポリシーを適用されていたため。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14053/a4186c31-dc6c-825e-10f0-fb82183bc1ff.png)

## 気付くきっかけ
原因を探るために、いろいろ検索していた中で下記サイトの「パスワードポリシーを適用する」のチェックを外す ***（簡単なパスワードを許可したい場合）*** の一文を見て、ようやく原因に気が付きました。
今となってはどうやって辿り着いたのか記憶がない。

https://pgmemo.tokyo/data/archives/1221.html

社内サーバーで使用するということで、もともとユーザー名とパスワードを一緒にしていました。バージョアップする際にも同じように設定したわけです。
これはパスワードポリシーにある「パスワードはユーザー アカウント名を含まない。」を満たしてないですね。

## パスワードポリシーとは
パスワードの複雑性のポリシーは、使用可能なパスワードの数を増やすことにより、総当り攻撃を防ぐようにデザインされています。 パスワードの複雑性のポリシーが適用される場合、新しいパスワードは次のガイドラインを満たしている必要があります。

* パスワードはユーザー アカウント名を含まない。
* パスワードは 8 文字以上である。
* パスワードは次の 4 つのカテゴリのうちの 3 つのカテゴリの文字を含む。
* ラテン文字の大文字 (A ～ Z)
* ラテン文字の小文字 (a ～ z)
* 算用数字 (0 ～ 9)
* 感嘆符 (!)、ドル記号 ($)、番号記号 (#)、パーセント記号 (%) などの英数字以外の文字
* パスワードには最大 128 文字まで使用できます。 パスワードはできるだけ長く、複雑にします。 

https://learn.microsoft.com/ja-jp/sql/relational-databases/security/password-policy?view=sql-server-ver16

# 暫定対応
「パスワードポリシーを適用する」のチェックを外した。

あまりいい対応ではないですが、上長が出張していたので今回は一旦これで対応しました。
パスワードポリシーに則ったパスワードを設定するようにした方がいいでしょう。

# 最後に
原因は分かってしまえば簡単なことだった。
エラーの「理由: このアカウントのパスワードを変更する必要があります。」も原因が分かれば確かにその通りなんですよね。

アプリケーションは、バージョアップ前と何も変えていないのでそのまま動作するはずだし、パスワードはユーザーと綴りも一緒で正しいと思っているわけですから、パスワードポリシーとは頭の片隅にも思ってなかった。
なので役割とか権限周りの設定とか何度も見直したし、ユーザーも何度も作り直した、それでもエラーで接続できない。もう「わからない、わからない」って何度も呟きながら数時間かかってようやく解決です。
[Elasticsearch]配列内の要素数が一定以上のドキュメントを検索したい

## これはなに
`Elasticsearch` で配列として要素が格納されているフィールドに対して、要素が一定数存在するかで検索する方法を調べた際の備忘録です。

## 結論

例として ids というフィールドに配列要素が格納されていた場合、
以下のようなコードで検索が行えます。

```json
{
  "query": {
    "bool": {
      "must": [
        {
          "bool": {
            "filter": {
              "script": {
                "script": "doc['ids'].length > 5"
              }
            }
          }
        }
      ]
    }
  }
}
```

script を使うことでフィールドの要素数を `length` で参照することができるので、それを利用する形です。
script を使用しない方法がないかも調べてみましたが、見つかりませんでした...

## script とは？

https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-script-query.html

https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-scripting-using.html

https://www.elastic.co/guide/en/elasticsearch/painless/current/painless-field-context.html

script を使用すると、Elasticsearch でカスタム式を評価できます。
計算された値をフィールドとして返したり、クエリのカスタム スコアを評価したりできます。

通常のクエリでは行えない検索方法も script を使用することで実現することもできます。
ただ、場合によっては[検索速度が遅くなる](https://www.elastic.co/guide/en/elasticsearch/reference/current/scripts-and-search-speed.html)こともあるようなので、使用する際はそのあたりも注意する必要がありそうです。
【Tauri + React】リンクをブラウザで開く方法

# 概要
TauriでリンクをOSのブラウザで開く方法です。普通にaタグのhrefにリンクを書くだけではもちろんTauriのアプリケーション内でリンクが開かれてしまいます。

# 解決法
aタグのtarget属性に`_blank`を設定してあげればブラウザで開くことができます。
```react:App.tsx
return(
    <>
        <a href="https://~~">Tauriのアプリ内で開きます</a>
        <a href="https://~~" target="_blank">ブラウザで開けます</a>
    </>
)
```
AnimateCC シンボルにプログラムをリンケージ+データ渡し

https://qiita.com/aichime/items/577af749bfa342d6087f

の続きで、
シンボルにクラスを紐付けることはできたのですが、
生成したオブジェクトに引数も渡したいなって思って、
ここもちと考えてました

# データ引き渡し用のクラスを用意
データ引き渡し用のクラスを別途用意したいと思います
上記の記事のAbstractDispクラスを少し変更します
```JavaScript
class AbstractDisp{
	protected _myDisp:createjs.MovieClip = null;
	protected _lib:any = null;

	constructor(current:createjs.MovieClip, lib:any){
		this._myDisp = current;
		this._lib = lib;
		this._myDisp.stop();
		this._init();
	}

	protected _init():void{
	}
}
```
これを継承して、AbstractItemクラスを用意
```JavaScript
class AbstractItem extends AbstractDisp{
	constructor(current:createjs.MovieClip, lib:any){
		super(current, lib);

		if(this._myDisp.data !== undefined){
			this._setData(this._myDisp.data);
		}
	}

	protected _setData(data:any):void{
		throw new Error("AbstractItem._setData() Abstract Method!");
	}
}
```
このクラスは、シンボル生成時に data プロパティが存在していたら _setData() メソッドを呼び出します

# Itemクラスに AbstractItem を継承
続いて、動的生成する Itemクラス
```JavaScript
class Item extends AbstractItem{
	constructor(current:createjs.MovieClip, lib:any){
		super(current, lib);
	}

	protected _init():void{
		this._myDisp.alpha = 0;
		this._myDisp.scale = 0;
	}

	protected _setData(data:any):void{
		createjs.Tween.get(this._myDisp).wait(100 * data).to({scale:1, alpha:1}, 1000, createjs.Ease.circOut);
	}
}
```
もらう data には、生成した順番を渡してもらいます
この順番に100ミリセックを掛けて、生成順に徐々に出現するようにしてあります

最後に Mainクラス
```JavaScript
class Main extends AbstractDisp{
	constructor(current:createjs.MovieClip, lib:any){
		super(current, lib);

		this._displayItem();
	}

	private _displayItem():void{
		const XNUMS:number = 5; // 横の数
		const YNUMS:number = 3; // 縦の数
		const GRID:number = 100; // グリッド
		const LEFT:number = 100; // 左
		const TOP:number = 100; // 上

		let cnt:number = 0;
		let i:number, i2:number;
		for(i = 0; i < YNUMS; i++){
			for(i2 = 0; i2 < XNUMS; i2++){
				let item:Item = new this._lib.Item();
				item.data = cnt++; // ここで生成した順番を data にセットする
				item.x = LEFT + GRID * i2;
				item.y = TOP + GRID * i;
				this._myDisp.addChild(item);
			}
		}
	}
}
```
実行すると、横に5つ、縦に3つ、計15個の Itemオブジェクトが徐々に表示されます

# まとめ
これでデータの受け渡しもできるようになりました
ただしこれだと data プロパティが1つだけなので、もし複数のデータを渡したいときは、
``` data = {a:hoge, b:hoge2}; ```
みたいに、オブジェクトを渡せばいいのかなと思います
Windows10でYOLOXを動かすときのエラーと対策

Windows10でYOLOXを動かしてみたら色々とエラーがでて苦戦したので、エラーと対策をまとめてみました。

## subprocess.CalledProcessError: Command '['where', 'cl']' returned non-zero exit status 1.

### 内容

Visual Studioの環境変数が通っておらず、clコマンドが実行できないというエラー。

### 対策

VisualStudioの環境変数を設定します。パスの内容は自身の環境に合わせて適宜変更してください。

１．PATHに以下の2つのパスを追加
```
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\bin\Hostx64\x64
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE
```

２．LIBという環境変数を作成し以下の3つパスを追加
```
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64;
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.19041.0\ucrt\x86;
C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86
```

３．INCLUDEという環境変数を作成し以下の2つのパスを追加
```
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\include
C:\Program Files (x86)\Windows Kits\10\Include\10.0.19041.0\ucrt
```

## subprocess.CalledProcessError: Command '['ninja', '-v']' returned non-zero exit status 1.

### 内容
ninjaの更新によりninja --vというコマンドが使えなくなっている。

### 対策
__PYTHONのインストール先__\Lib\site-packages\torch\utils\cpp_extension.pyの_run_ninja_buildメソッドを以下の通り修正する。

```python:修正前
command = ['ninja', '--v']
```

```python:修正後
command = ['ninja', '--version']
```

## ModuleNotFoundError: No module named 'yolox.layers.fast_cocoeval
### 内容
importエラー。

### 対策
YOLOX/yolox/evaluators\coco_evaluator.pyの291行目を以下の通り修正する。

```python:修正前
from yolox.layers import COCOeval_opt as COCOeval
```

```python:修正後
from pycocotools.cocoeval import COCOeval
```