OmniAICreator/Qiita-1.07M huggingface dataset:
Unity内で特定のスクリプトがアタッチされているオブジェクトを検索する方法

Unityのプロジェクトを開いている際、特定のスクリプトがどのオブジェクトにアタッチされているのか調べる方法です。

# 手順
1. 検索したいスクリプトの.metaファイルを開きます。
2. 開いた.metaファイル内にguidが記載されているのでコピーします。
   <img width="400" alt="guid" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368729/d606b0c3-25f4-edf0-3034-db439b8bd6a4.png">
3. gitを開きgrepを行います。
   ```
   git grep 6981db99d27fc3a4f88159995e93e24e
   ```
4. スクリプトがアタッチされているすべてのスクリプトが表示されます。
   <img width="700" alt="grep" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/368729/6f7d776a-2bba-da43-5f6c-36d06d4e6e10.png">
【R】複数のテーブルをまとめてYAML形式で保存する

Rでデータを保存するときには、CSV形式などでテーブル1つを1ファイルで保存することが多いですが、複数の表をYAML形式で1つのファイルにまとめて保存することができます。

### テーブルをYAML形式で保存する

まず、1つのテーブルの保存です。

```R:write_table1a.R
library(tidyverse)
library(yaml)

table1 <- data.frame(a=c(1,2,3),b=c(10.3,11.6,12))
write_yaml(table1, "table1a.yaml")
```

保存されたファイルはテキストになっていますので、テキストエディタなどで読むことができます。

```YAML:table1a.yaml
a:
- 1.0
- 2.0
- 3.0
b:
- 10.3
- 11.6
- 12.0
```

列単位のベクトルになっています。
行数が多くなると、行単位で保存した方がテキスト見る場合読みやすいように思います。

```R:write_table1b.R
write_yaml(transpose(as.list(table1)), "table1b.yaml")
```

```YAML:table1b.yaml
- a: 1.0
  b: 10.3
- a: 2.0
  b: 11.6
- a: 3.0
  b: 12.0
```

ファイルからデータを読むには、後者は少し工夫がいります。

```R:read_table1a.rb
table1a <- data.frame(read_yaml("table1a.yaml"))
table1b <- map_dfr(read_yaml("table1b.yaml"), as.data.frame)
```

### 複数のテーブルを1つにまとめて保存

複数テーブルをリストとしてまとめて1つのファイルに保存できます。

```R:write_table_data.R
table2 <- data.frame(a=c("A", "B"),b=c(3,4))
data <- list(table1_data=table1, table2_data=table2)
write_yaml(data, "table_data.yaml")
```

ファイルを読み込むと、保存したデータと同じテーブルのリストになります。

```R:read_table_data.R
table.data <- read_yaml("table_data.yaml")
table1.data <- data.frame(table.data$table1_data)
table2.data <- data.frame(table.data$table2_data)
```

### Rubyプログラムで読み書きする

YAML形式は多くのプログラミング言語でサポートされているので簡単に読み書きできます。
Rubyの例を示します。Hashクラスのデータとして読み込まれます。(keyはStringクラスになっています)

```Ruby:read_write_table_data1.rb
require "rover-df"
require "yaml"

# 読み込み
table1a=Rover::DataFrame.new(YAML.load_file("table1a.yaml"))
table1b=Rover::DataFrame.new(YAML.load_file("table1b.yaml"))

table_data=YAML.load_file("table_data.yaml")
table1_data=Rover::DataFrame.new(table_data["table1_data"])
table2_data=Rover::DataFrame.new(table_data["table2_data"])

# 書き込み
table_data2={"table1_data"=>table1_data.to_h, "table2_data"=>table2_data.to_h}
open("table_data2.yaml", "w"){|f| f.puts table_data2.to_yaml}
```

RのlistとRubyのHashはYAML形式で互換性があります。しかし、YAMLではRubyのシンボルに相当するクラスは定義されていないようで、Rとのデータのやり取りにはHashのkeyをStringクラスにしておく必要があります。
以下のように、symbolize_keysとstringify_keysでHashのキーString,Symbol間で変換できます。

```Ruby:read_write_table_data2.rb
require "rover-df"
require "yaml"
require "active_support"
require "active_support/core_ext"

# 読み込み
table1a=Rover::DataFrame.new(YAML.load_file("table1a.yaml").symbolize_keys)
table1b=Rover::DataFrame.new(YAML.load_file("table1b.yaml").map(&:symbolize_keys))

table_data=YAML.load_file("table_data.yaml")
table1_data=Rover::DataFrame.new(table_data["table1_data"].symbolize_keys)
table2_data=Rover::DataFrame.new(table_data["table2_data"].symbolize_keys)

# 書き込み
table_data2={"table1_data"=>table1_data.to_h.stringify_keys, "table2_data"=>table2_data.to_h.stringify_keys}
open("table_data2.yaml", "w"){|f| f.puts table_data2.to_yaml}
```
`flutter doctor --android-licenses`が失敗する

# 環境
- android studio beta (2021.3)
- windows 10

# エラー内容
```
flutter : エラー: メイン・クラスcom.android.sdklib.tool.sdkmanager.SdkManagerCliを検出およびロードできませんでした
発生場所 行:1 文字:1
+ flutter doctor --android-licenses 2> log.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (エラー: メイン・クラスcom...出およびロードできませんでした:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError
 
原因: java.lang.ClassNotFoundException: com.android.sdklib.tool.sdkmanager.SdkManagerCli
```
※文字化けした為、`2> log.txt`でファイル出力した

# 対策
1. `{android-sdk}/cmdline-tools/latest`を削除
1. 再インストール

# 参考
https://stackoverflow.com/questions/60727326/sdkmanager-error-could-not-find-or-load-main-class-com-android-sdklib-tool-sdk
PythonのList Comprehension (listcomps) の使い方

Pythonでlist型の新規作成には、listcompsを使用できる。

```python
word = 'ABC'

# listcomps　可読性が高い
codes = [ord(c) for c in word]
# [65, 66, 67]

# 同じことをfor文で繰り返し処理の場合
for c in word:
  codes.append(ord(c))
```

また、下記のようにmapとfilterを使用すれば、listcompsと同じ処理を実現可能。
可読性はやはりlistcompsが上だと感じる。（個人的にそう感じる。）

```python
# listcomps
codes = [ord(c) for c in word if ord(c) > 127]
# map　と　filter
codes = list(filter(lambda c: c > 127, map(ord, word)))
```

listcompsは複数のfor文も使用できるので、便利。

```python
clothes = [(color, size) for color in colors for size in sizes]
# [('black', 'S'), ('black', 'M'), ('black', 'L'), ('white', 'S'), ('white', 'M'), ('white', 'L')]
```
Macにiterm2を入れてみた！

Macでデフォルト以外のターミナルが使いたくてiterm2をインストールをしてみました。

コマンドとかが全くわからなかったのでとりあえず調査。
最初に見た記事のコマンドを叩くと、以下のエラーメッセージが。。

<pre>$brew cask install iterm2
Error: Unknown command: cask</pre>

いくつか調べたところ、cskコマンドの使い方が変わったらしいことが判明。
コマンドではなく、オプションに変わったらしい。
cskコマンドすら知らなかったのに、
なんでオプションになってるんや。。と悲鳴を上げつつ以下のコマンドを実行。
<pre>$ brew install iterm2 --cask</pre>

なんやかんや、ぶわーっとメッセージが出力され、インストール成功！！
<pre>iterm2 was successfully installed!</pre>

以下の記述の「iterm2」の部分を
インストールしたいアプリ名に変更すれば応用可能だと思われる。
<pre>$ brew install iterm2 --cask</pre>

本記事は以下の記事を参考に作成致しました。
めっちゃわかりやすく書いてくださっているので、
一発でインストールできます！٩(๑❛ᴗ❛๑)۶
https://qiita.com/luton-mr/items/83386f43c395ecec7736

なお、上記の記事ではMacOSのバージョンが「Big　Sur」となっているが、
今回は、「Monterey」
IntelliJ IDEAの日本語化

# 記事作成の経緯
インストールしたてのIntelliJの表示言語がすべて英語であるので非常に使いづらいと感じ、表示言語を日本語へ変更するやり方をQiitaの記事を参考にやってみたが、変更することができませんでした。その為、2022年のIntelliJ IDEAの日本語化のやり方をこの記事に残しておきます。

# 前提条件
IntelliJはインストール済みとしておきます。

# 方法
1. intelliJを起動して表示される初期画面の左にあるPluginをクリック。
1. 画面上部に表示されるMarketPlaceタブを選択し、検索欄に"日本語"と入力。
1. 検索結果に表示される"Japanese Language Pack/日本語言語パック"をインストール。
1. IntelliJを再起動させる。

# 以前までの方法
こちらの方法を参考にしておりました。今はIntelliJそのものに追加されているようなので、こちらの方法ではうまくいかないのかもしれません。

https://qiita.com/daigoro7/items/00819e5686f6c4d682f8
DyanmoDBのテーブル設計



# はじめに
Dynamoテーブルの設計で、参考になった内容を紹介します。

:::note info
　試験対策：AWS 認定 データベース – 専門知識(AWS Certified Database – Specialty)
:::
# 目次
- DyanmoDBのテーブルのキー設計
  - パーティションキー設計
  - LSI設計
  - GSI設計
  - サイズの大きい属性の設計
  - その他

# DyanmoDBのテーブルのキー設計
- クエリパターンを洗い出し、適切なLSIやGSI選択

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-general-nosql-design.html

- スキャン禁止
　スキャンは大量のシステムリソースを消費する

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/SQLtoNoSQL.ReadData.Scan.html

## パーティションキー設計
- パーティションキーをユニーク設定し、ワークロードを分散
　パーティションで分散して、クエリを効率よく実施できるようにする

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-partition-key-uniform-load.html

- ホットパーティション（アクセス頻度高い）とコールドパーティション（アクセス頻度低い）でテーブルを分ける
　キャパシティはパーティションごとに分配されるため、単一のパーティションにアクセスが集中するとスロットリングが起こる可能性がある

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-partition-key-design.html

## LSI設計
- インデックスが必要であれば、LSIを使用
　※LSIは最大10GB

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html#LSI.Creating

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/SecondaryIndexes.html

- 強力な整合性「ConsistentRead 」が必要な場合は、プライマリーキーやLSIを使用

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html#LSI.ThroughputConsiderations

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-indexes-general.html

### 読み込みは結果整合性を使用

　キャパシティのコスト削減、
https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/LSI.html#LSI.ThroughputConsiderations

## GSI設計
- 非キー属性に対するクエリの速度を上げる必要がある場合に使用

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html

- 結果整合性のデータ取得となる考慮

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GSI.html#GSI.tableclasses

- パフォーマンスを必要とするクエリの対応

　テーブルのレプリカ（GSI）を作成し、パフォーマンスを必要とするクエリで最大のキャパシティを使用可能


https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-indexes-gsi-replica.html

## サイズの大きい属性

　・圧縮して格納
　・データの扱い方
　　メタデータはDynamoDB（検索等に使用）
　　オブジェクトはS3を使用

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/bp-use-s3-too.html

## その他
・attribute名は分かりやすい名称にする
nextのnpm run devで立ち上がらない

ディレクトリが違った。
nextjs_hp/next_hpと同じ名前を二つ繋げてたのが良くなかった。
~ cd nextjs_hpと記入しても下層にディレクトリが移動していなかった。
~ lsで一覧を見て、コピペしたら移動して~ npm run devが効くようになった。

extjs_hp % npm run dev
npm ERR! code EJSONPARSE
npm ERR! path /Users/〜〜〜〜〜/nextjs_hp/package.json
npm ERR! JSON.parse Unexpected string in JSON at position ~~ while parsing '{
npm ERR! JSON.parse   "dependencies": {
npm ERR! JSON.parse     "tailwindcss":'
npm ERR! JSON.parse Failed to parse JSON data.
npm ERR! JSON.parse Note: package.json must be actual JSON, not just JavaScript.

npm ERR! A complete log of this run can be found in:
Jmeterのインストール手順

# インストール
## 1. JDKをインストールする
https://qiita.com/yurihyp/items/c16247815405e3154a65

## 2.Jmeterをインストールする
ターミナルで以下を実行。
```
brew install jmeter
```

## 3.Jmeterを起動
```
jmeter
```

こんなGUIが開くはず。

![スクリーンショット 2022-06-23 23.05.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632129/e0218302-77f1-1c27-82bb-f71724a609d9.png)
Googleの検索能力の高さに驚愕したので共有させてください（恐怖）

## 概要

今日とても驚いたことがあったので、簡潔にまとめようと思います。

**Googleの検索能力の高さのことです。**

もし時間があったらぜひ試してみてください。


## 経緯

日常の作業をしていたときのことです。

- Google ドライブの中にある**ファイルを検索しよう**としたときのこと

- 「xx大学」という**キーワードで検索した**


- **いくつかのファイルがヒットした**

ここまでで、まあもちろんキーワード検索をドライブ内で行っただけなので、
普通ですよね。
いくつかの書類がヒットしたわけです。

### あれ、何でヒットした？？

しかし、ここで、「あれ？」と思いました。

ヒットしたファイルの中には、**pdf**ファイルがあったのです。
pdfファイルのタイトルは、なんら関係のない「document123.pdf」
みたいな感じでした。

最初はなにも思わなかったのですが、ふと、
**「え、これってpdfの中身をその場でOCRしてんの！！！？？？？」**
と鳥肌が立ちました。

私は約５０GBのファイルをドライブに入れているのですが、
検索時間は数秒でした。

「もし検索ワードに対してOCRかけて一致ヒットさせていたらやばくないか、、？？」

と思いました。


### OCRほんとに裏でやってんの？？

横にいた同僚にこれを話したところ、

**「pdfって画像としてではなくメタデータも保持しているんだっけね？」**

となりました。

そこで、私は少しホッとしました。なぜなら、
「もしpdfがヒットした理由が、メタデータに私が検索したワードが含まれており、そこに対してヒットして表示された」
のかなと思ったからです。

**メタデータに対して全文検索がかかったのなら、まあ理解できるな、と。**

これを確かめたくなった私は、以下のことを試してみました。

- 手元にあった**請求書をアイフォンで撮影**
- 撮影された画像（HEICフォーマット）を、**pdf, png, jpeg に変換**
- **Googleドライブにアップロード**
- 請求書に書かれていた**ワード「三井住友」とか、「支払い期限」で検索**

これで、どうなったと思いますか？？？？

結果は、

- pdf
- png
- jpeg

の**画像ファイルが見事ヒットしました。**（HEICだけヒットしませんでしたが）

### たぶんOCRリアルタイムでやってるわ

いや、鳥肌が立ちましたね、
**画像ファイルなので、確実に裏でOCRしていると思います。**

また、**その場でアップロードしたファイルなので、
何らかの分析が裏で前もって行われている可能性も低く、**

**「リアルタイムで検索ワードに対してOCRかけて結果を返している」**

ということでしょう。


### ファイルの中身すらGoogleは全部見えている

正直なところ、便利だという一方で、
**「Googleは全てのファイル（画像も含めて）の中身をAIでこんなに簡単に解析できるのか」、**
と怖い気持ちも覚えたというのが本音です。



## 終わりに

今回はこの「Googleの検索能力の高さ」
に驚き、怖ささえ覚えてしまったので記事を書いてしまいました。
これって別に驚くことではないんでしょうかね、もうこのくらいの検索能力は普通なのか、、？

今書いていて思いついたのですが、（流石に実現しないと思うけど、したら怖すぎる）


### もしかしたら音声データや動画データもリアルタイムでキーワード検索可能、、？

「自分が喋っている音声データ」

をドライブに上げてみて、これがもし検索ワードに対して一致して返ってくる

みたいなこともあったりするんですかね、、？？？

もしかしたら動画もとか。


試した人がいたら教えてください。（私も試せたらやってみます。）




というわけで今回はこの辺で。
読んでいただきありがとうございました。


@kenmaro 


## 追記

会社の方に

https://drive-hack.com/google-drive-search/

こんな記事があることを教えていただき、
OCRはもう２年くらい前（もっと前かも？）から実装されていることがわかりました。

- Googleの検索能力の高さ、
- そして私の検索能力の低さ

がわかった
というオチもできたので、ここで終わりです。


読んでいただきありがとうございました。
性能テストの種類

## 負荷テスト

負荷テストの目的は、どの時点でアプリケーションのパフォーマンスが低下し始めるかを知ること.
負荷テストは、アプリケーションが100人のユーザーで動作することを想定している場合、90～110人のユーザーで負荷テストを行うというように、通常の状態で行われる。

## ストレステスト
ストレステストの目的はどの時点でアプリケーションが落ちるかを知ること。
ストレステストは,アプリケーションが100人のユーザーで動作していることを想定している場合、もっと大量のユーザーが訪れているような異常は状態を再現する。

## ボリュームテスト
ボリュームテストでは、アプリケーションを重いデータベースサイズでテストする。
ユーザー数は一定でも、データベースのサイズは大きくなる。
このテストは、主にアプリケーションがデータベースと大量のインタラクションを持つ場合に使用される。

## スパイクテスト
ストレステストに似ているが、異なる点は'突然'ユーザー数が上昇した場合にどうなるかをテストする点。
Qiita Conference 2022 復習

 エンジニア向けオンライントークイベント「Qiita Conferece 2022 
2022/6/23(木) 17:20-21:35 24(金) 17:20-21:40

https://qiita.com/official-campaigns/conference/2022?utm_source=headertextbanner&utm_medium=qiitaconference&utm_campaign=text3


Qiita Conference 2022 予習
https://qiita.com/kaizen_nagoya/items/a6ab098dbe6a1ae35368

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">笑顔　といいながら　面白顔　のところが偉い。<a href="https://twitter.com/hashtag/Qiita?src=hash&amp;ref_src=twsrc%5Etfw">#Qiita</a> <a href="https://twitter.com/hashtag/%E7%84%A1%E9%A7%84?src=hash&amp;ref_src=twsrc%5Etfw">#無駄</a> すごく価値があるし、凄いなと思った。</p>&mdash; naokiakutagawa (@naokiakutagawa) <a href="https://twitter.com/naokiakutagawa/status/1539903084339417088?ref_src=twsrc%5Etfw">June 23, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 復習

株式会社無駄 / 代表取締役社長　藤原 麻里菜
>頭の中に浮かんだ不必要な物を何とか作り上げる「無駄づくり」を主な活動とし、YouTubeを中心にコンテンツを広げている。
2013年からYouTubeチャンネル「無駄づくり」を開始。現在に至るまで200個以上の不必要なものを作る。2016年、Google社主催「YouTubeNextUp」に入賞。2018年、国外での初個展「無用發明展- 無中生有的沒有用部屋in台北」を開催。25,000人以上の来場者を記録した。2020年 Forbes Japanが選ぶ「世界を変える30歳未満」30 UNDER 30 JAPANに選出される。
無駄なことを考えるためのアウトプットと発想法
・考えるってなんだろう？
・生活のなかで工夫してアウトプットを作っていく方法
・無駄づくり発想術

考える術（ダイヤモンド社）

https://www.amazon.co.jp/dp/B08N694ZFZ/

無駄なマシーンを発明しよう（技術評論社）

https://www.amazon.co.jp/dp/B0998CX7DM/

順次追記します。

# 感想

藤原麻里菜　さんの３つの顔を知る。

1. 写真
ちょっと緊張してる？

2. 生放送
話はとてもわかりやすかった。
しっかりしている感じがした。

3. 動画

生放送の中で紹介のあった動画の中の表情が、素直でとても好感を持てた。

最近の無駄づくりまとめ | 2020年6-10月

https://www.youtube.com/watch?v=tUx2-HJsNDc

なんか、投資家か年寄りのよくある上から目線っぽい感想でごめんなさい。

https://www.youtube.com/c/mudadukuri

【発明】入ったまま出掛けられる「こたつ」を作ってみた　| 無駄づくり　Outdoor Moving Kotatsu - Useless Inventions

https://www.youtube.com/watch?v=KwzVriMEcK4

【頭がおかしい通販番組】らくらくハイタッチくん | 無駄づくり

https://www.youtube.com/watch?v=J_TdfNFSUGc

MUDA COLLECTION 2022 SUMMER

https://www.youtube.com/watch?v=lMZBURfrqZU

4. 内容

「役に立たない」科学が役に立つ（翻訳本）

https://ithems.riken.jp/ja/news/usefulness-useless-knowledge

“有用性” を捨てよ、“無駄” の旅に出よう。
発明家・藤原 麻里菜が見つめる『無駄づくり』の真髄とは

https://www.freaksstore.com/freakmag/project/wasted_creation/

# 参考資料
上から目線が止まらない

https://qiita.com/kaizen_nagoya/items/bfa4f7943f5fcf700cba

人格改造　あいうえお。仮説（185）

https://qiita.com/kaizen_nagoya/items/bfae8b4a486ee5fd72de

文字鏡

日本語語彙大系

ちょけねこ

社外取締役

記事見直し　謝罪

無駄　連携

保養　休み

＜この記事は個人の過去の経験に基づく個人の感想です。現在所属する組織、業務とは関係がありません。＞
# 文書履歴(document history)
ver. 0.01 初稿 　20220623
ver. 0.02 ありがとう追記 20230502
### 最後までおよみいただきありがとうございました。
いいね　💚、フォローをお願いします。
####  Thank you very much for reading to the last sentence.
Please press the like icon 💚　and follow me for your happy life.
スナップショット とは？EBSとAMIの違いも見てみた

## 勉強前イメージ

EBSのスナップショットとかその時の瞬間を残しておくような感じ？
AWS用語なのかな？
バックアップ？

## 調査

### スナップショット とは

AWS用語ではなく、ITの分野の用語では
ある時点におけるデータやファイルなど全体像を写し取ったものを表します。

バックアップする際に、バックアップ中にファイルの更新がされてしまうと
復元した際のファイルやディレクトリに不整合が起こったりすることがあります。
それを防ぐのがスナップショットで、ある時点でのデータの状態を保持しているので不整合を防ぐことが出来ます。

ただし、スナップショットはバックアップではないのです。
スナップショットは元のデータを丸ごとコピーしているわけではなく、
スナップショットを取った際の瞬間のシステム状態を記録しているので
`元のデータが破損すれば復旧が不可能` になります。
これが、バックアップとの違いになります。

### EBSのスナップショットは？

EBSのスナップショットも同様、EC2のその瞬間の `EBSの中のデータ` を丸ごと保存したものになります。
ただし、スナップショットはインスタンスの構成(インスタンスタイプ等)は含まれておらず
インスタンスの構成はスナップショットと同様に `AMI` に保存されます。

それぞれの違いは以下になります。

- スナップショット : ある瞬間のEBSの中のデータを保存したもの
- AMI : スナップショットとインスタンスを構成する情報が入った起動のテンプレート

## 勉強後イメージ

ちょっと勘違いしてたかも。
スナップショットって言葉はバックアップだと思ってたけど、元データ壊れたら復旧できないのか。
ただEBSのスナップショットはバックアップの意味はあるようなきがする・・・AMIとセットだけど。

## 参考

- [ストレージの機能 スナップショットとは？その用途や特徴、バックアップとの違いを解説](https://www.storage-channel.jp/blog/what-is-snapshot.html)
- [AWS運用におけるスナップショットを用いたバックアップ戦略](https://aws.taf-jp.com/blog/26786)
人工知能学会2022&2021年の集計

# 人工知能学会2021と2022の集計
今年は2年ぶりの現地開催+オンラインになりました。
現地では1600名ほどの参加があったみたいです。2020年のリベンジで来年こそは熊本で現地開催できることを願ってます。

前と同じく単純な集計結果です。
一般セッション、インタラクティブセッション、オーガナイズドセッション、学術機関(大学、大学院、専門学校、国立研究所)、民間企業の発表件数、著者数を抽出してまとめた。
国際セッションは英語→日本語変換が面倒なのと、名寄せも面倒なので株式会社と(株)を取り除くくらいしかやってません。

## JSAI2022
ホームページ： http://ai-gakkai.or.jp/jsai2022/
日時：2022年6月14日（火）～17日（金）
会場：国際会館（京都府京都市）

### 学術機関の発表件数(2022年)

| 順位 | 組織             | 件数 |
|------|------------------|------|
|1|	東京大学	|213
|2|	慶應義塾大学	|129
|3|	早稲田大学	|74
|4|	筑波大学	|67
|5|	名古屋大学	|59
|6|	産業技術総合研究所	|57
|7|	理化学研究所	|56
|8|	立命館大学	|54
|9|	大阪大学	|53
|10|	京都大学	|51

例年通り東大が首位。東大、慶應、早稲田はだいたTOP3。
理研ももっと数があったのですが、
2019、2020年同様に表記が揺れまくってたためうまく集計できてません。
理研の皆様におかれましては何卒組織の表記方法を統一して頂ければ。


### 民間企業の発表件数(2022年)
| 順位 | 組織                                | 件数 |
|------|-------------------------------------|------|
|1|	日本電信電話|	40
|2|	NTT|	29
|3|	八千代エンジニヤリング|	21
|4|	富士通|	20
|5|	日立製作所|	19
|6|	サイバーエージェント|	17
|7|	ヤフー|	14
|7|	日本電気|	14
|7|	野村アセットマネジメント|	14
|8|	NTTコミュニケーションズ|	12

今年は日本電信電話とNTTがワンツー。
また、八千代エンジニヤリングと富士通は20件以上。

### 著者別発表数(2022年)
| 順位 | 氏名        | 件数 |
|------|-------------|------|
|1|	栗原聡	|15
|2|	松尾豊	|13
|3|	小林一郎	|12
|4|	鳥海不二夫	|9
|5|	坂田一郎	|9
|6|	谷口忠大	|9
|7|	井原史渡	|7
|7|	岡田将吾	|7
|7|	中川慧	|7
|7|	大西正輝	|7

栗原先生が2021年に引き続き1位。
松尾先生、鳥海先生、井原先生が二年連続でランクイン。


## JSAI2021
ホームページ： http://ai-gakkai.or.jp/jsai2021/
日時：2021年6月8日(火)～11日(金)
会場：オンライン開催(Zoom)


###学術機関の発表件数(2021年)


| 順位 |        組織        | 件数 |
|:----:|:------------------:|:----:|
|1	 |東京大学	|130
|2	|慶應義塾大学	|70
|3	|理化学研究所	|68
|4	|早稲田大学	|66
|5	|大阪大学	|63
|6	|筑波大学	|54
|7	|電気通信大学	|46
|8	|産業技術総合研究所	|43
|9	|名古屋工業大学	|43
|10	|京都大学	|37

東大強い。理研ももっと数があったのですが、
2019、2020年同様に表記が揺れまくってたためうまく集計できてません。
理研の皆様におかれましては何卒組織の表記方法を統一して頂ければ。(二回目)

### 民間企業の発表件数(2021年)

| 順位 |                 組織                | 件数 |
|:----:|:-----------------------------------:|:----:|
|1|	八千代エンジニヤリング|	25
|2|	日本電信電話	|24
|3|	NTT コミュニケーション科学基礎研究所|	19
|4|	日立製作所|	17
|5|	サイバーエージェント|	16
|6|	中外製薬|	10
|7|	日本電気|	9
|8|	日本電信電話 セキュアプラットフォーム研究所|	9
|9|	パナソニック|	8
|10|	UACJ|	6
|10|	キヤノン|	6
|10|	有限責任監査法人トーマツ|	6

八千代エンジニヤリングが首位。日本電信電話、NTT基礎研、日立、サイバー、中外製薬が10件以上の発表。例年同様だが企業ブースを出しているところが多い。


### 著者別発表数(2021年)

| 順位 |     氏名    | 件数 |
|:----:|:-----------:|:----:|
|1|	栗原聡	|11
|2|	後藤正幸|	9
|3|	長井隆行|	8
|4|	鳥海不二夫|	7
|4|	松井藤五郎|	7
|4|	松尾豊|	7
|5|	森直樹|	6
|5|	井原史渡|	6
|5|	堀井隆斗|	6
|5|	武藤敦子|	6
|5|	森山甲一|	6
|5|	犬塚信博|	6

栗原先生が首位。
例年よりも皆さん少ないのは現地開催じゃなかったからやる気があまり出なかった可能性があるのではないでしょうか。（私はそうでした）
cronって、シンボリックリンクを認識しないの？

OSのリプレースのため、ubuntuサーバーを立ち上げてcronセッティングしていた昼下がり。

```python
0 20 * * * python /home/ore/Documents/py/soft.py
```

普通に単純にcronを記述して、完璧に動作されるはずだった。
しかし動作しない。

・soft.py（動作させたいファイル）のパーミッションの問題？
・cronのパーミッションの問題？
・ファイルパス指定の間違い？

悩んだ結果、「python」コマンドを「python3.8」と書き換えたら解決した。

```python
0 20 * * * python3.8 /home/ore/Documents/py/soft.py
```

はじめのコードで記述したpythonは、
/usr/bin/python3.8のシンボリックリンクである。

これをそのまま本体のpython3.8に書き換えただけ。
今までも当然のようにシンボリックリンクで指定していた気がしたけどなぁ。

やっぱ、シンボリックリンクが原因なの？
【機械学習】sklearnによるRidge回帰、Lasso回帰、Elastic Net回帰の実践

# はじめに
Ridge回帰、Lasso回帰、Elastic Net回帰についてまとめました(もっと追記していきます)。

# 正則化
これらの回帰を理解するにあたって、正則化というものがキーとなります。
正則化は、ペナルティを課すことでモデルの過学習を抑制する手法です。
学習データへのモデルの依存を減らした上で、最もフィッティングできるパラメータ(重み)の組み合わせをみつけることができます。
通常の線形回帰だと過学習によってバリアンスが大きくなるので、これを小さくするためにバイアスを増やすイメージです(バリアンスとバイアスのトレードオフ)。

機械学習の回帰問題に正則化を適用するとき、以下の3つのアプローチが代表的です。
各アプローチで、ペナルティ項がそれぞれ異なります。
- Lasso回帰(L1正則化)
- Ridge回帰(L2正則化)
- Elastic Net回(L1+L2正則化)

# Ridge回帰
予測性能誤差をErrorとすると、Ridge回帰では、ペナルティ項に重みの平方和の合計を用います(L2ペナルティ)。
モデル学習時は、正則化パラメータλの値によってペナルティ項の強さを調節します。
cross-varidationで最適なλを決定します。

><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/569054/3180851c-8917-4c2d-1a3a-5cb349ffdffe.png" width="500">

## 実践
Ridge回帰でcross-validationを行うには、`RidgeCV`を使用します。

以下でコメントしていますが、複数のα(λ)の候補(0.1, 1.0, 10.0)でcross-validationを行って、一番精度のよいαをモデルとして返してくれます。

```py
from sklearn.linear_model import RidgeCV

# デフォルトのcvはNone(Leave-One-Out cross-validation)
# 与えたalphas(λ)のうちNegative MAEが高い(高いほどいい)ものを返す
ridge_cv_model = RidgeCV(alphas=(0.1, 1.0, 10.0),scoring='neg_mean_absolute_error')
ridge_cv_model.fit(X_train,y_train)

# テストデータの予測
test_predictions = ridge_cv_model.predict(X_test)

# MAE, MSE, RMSEの導出
MAE = mean_absolute_error(y_test,test_predictions)
MSE = mean_squared_error(y_test,test_predictions)
RMSE = np.sqrt(MSE)
```

# Lasso回帰
Lasso回帰では、ペナルティ項に重みの絶対値の合計を用います(L1ペナルティ)。
Lasso回帰の特徴として、重要でない説明変数の重みを0にする点があります。
必要な変数だけモデルに利用されるため、開発者がどの変数が重要かを認識しやすくなります。

ただ、予測性能はRidge回帰の方が高いため、こちらの方がよく使われます。

## 実践
sklearnの`LassoCV`では、指定範囲内のαを探索するので、`RidgeCV`のようにαの候補を与える必要はありません。
```py
from sklearn.linear_model import LassoCV

# 1~100まで0.1刻みでαをかえる
lasso_cv_model = LassoCV(eps=0.1,n_alphas=100,cv=5)
lasso_cv_model.fit(X_train,y_train)

# テストデータの予測
test_predictions = lasso_cv_model.predict(X_test)
```

# Elastic Net回帰
Elastic Net回帰はLassoのL1ペナルティとRidgeのL2ペナルティを両方加えたアプローチです。
Lasso回帰のように説明変数を取り除くとモデル性能を落とすことに繋がりかねない、という問題点をカバーするための方法となります。

パラメータとしては以下のものがあります。
- alpha: 正則化の強さ。0以上の値を取り0だと線形回帰と同じ。
- l1_ratio: L1正則化とL2正則化の比率。0~1の値をとる。

## 実践

```py
from sklearn.linear_model import ElasticNetCV

# L1, L2ペナルティの比率をl1_ratioで指定する
elastic_model = ElasticNetCV(l1_ratio=[.1, .5, .7,.9, .95, .99, 1],tol=0.01)
elastic_model.fit(X_train,y_train)

# テストデータの予測
test_predictions = elastic_model.predict(X_test)
```

# 参考資料

https://www.udemy.com/share/103I003@geAjiIIbeAp6lHVBzVyuAuftmVcYHgO5YkABYiTzdgGLkL2ZAtnxAxL89ek4pF60/

https://qiita.com/Takayoshi_Makabe/items/8f6dcb25124b9dcb1ae8

https://di-acc2.com/programming/python/12845/#index_id3

https://di-acc2.com/analytics/ai/6335/
【SpringBoot】開発環境作成（VPSにデプロイ）

SpringBootの開発環境作成3回目です。
今回はVPSにデプロイします。


## 作成内容
[①Springプロジェクト作成](https://qiita.com/nmaolks/items/ac3860d78822d52bb81c)
[②BitBucketプッシュ](https://qiita.com/nmaolks/items/43dc670b6184d643c0b1)
**③VPSにデプロイ**
④Jenkins自動デプロイ

## VPS設定
こちらでSSH公開鍵の設定をしてます。

https://qiita.com/nmaolks/items/5e5b3aa41d671cd549d7

## 処理の流れ
①Gradle処理追加しJarファイル作成
②SFTPツールでJar送信
③Jarファイル権限変更
④serviceファイル作成
⑤起動コマンド実行

## Gradle処理追加しJarファイル作成

SpringプロジェクトのGradleに以下の処理を追加します。
アプリケーション（Jar）がデーモン化されます。
```gradle:build.gradle
bootJar {
    launchScript()
}
```
Ecripseを使用している場合「Gradleタスク」からビルドすることができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/979bf4d7-7629-dbde-e786-71ae72d2d5c5.png)

## SFTPツールでJar送信(VPS)

管理者がアプリケーションをインストールする場所は基本的に以下のディレクトリです。
`$ cd /usr/local`

上記ディレクトリからファイルを作成します。
`$ mkdir SpringExample`

ビルドしたファイルをFTPSツールでサーバにアップロードします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/433b80f6-69b4-9e98-e9e4-31cadaef9bd6.png)

## Jarファイル権限変更

権限変更します。
`$ chmod 700 SpringExample.jar `

権限を確認するコマンド
`$ ls -l`

オーナーのみ権限があることを確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/1eddbad8-9a42-34dc-2cb6-d4df82a87185.png)


## serviceファイル作成
ユニットファイルを作成します
`$ sudo vim SpringExample.service`

以下内容を追加します
`User`では操作するユーザを設定
`ExecStart`ではJarファイルを指定しています。
```service:/etc/systemd/system/SpringExample.service
[Unit]
Description=demo
After=network.target

[Service]
User=root
ExecStart= /usr/local/SpringExample/SpringExample.jar
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target

```
## 起動コマンド実行

起動します。
`$ systemctl start SpringExample`

現在のプロジェクトの状態を確認できます。
`$ systemctl status SpringExample`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/61f98ff0-960b-b7e4-6226-559a88fc9982.png)

IPアドレスで検索をかけるとデプロイしたプログラムがWeb上で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1234354/10525d33-ec5f-5d25-4253-08dd59ab2a66.png)
歪度、尖度の計算(Python)

# 背景

　単回帰による機械学習のモデルを作成する際に、説明変数が正規分布に従っているか調べるのに便利なので、歪度と尖度を算出する関数を作ってみました。どちらも0に近づくほど、正規分布に近い分布となります。

　正規分布でない場合、例えばべき分布だった場合はlogを取るなど、加工を加えます。

# 環境

　Google Colaboratory
　Python3
　pandas, numpy

# コード


```Python
# numpyなどのインポート
import numpy as np
import pandas as pd
```

```Python

# 歪度の計算関数

def waido(data):
  n = len(data) # サンプルサイズ
  s = np.std(data) # 標準偏差
  mu = data.mean() # 平均
  return (n / ((n-1) * (n-2))) * (((data - mu) / s) ** 3).sum()

# 尖度の計算関数

def sendo(data):
  n = len(data) # サンプルサイズ
  s = np.std(data) # 標準偏差
  mu = data.mean() # 平均
  return ( ((n * (n+1)) / ((n-1) * (n-2) * (n-3))) * (((data - mu) ** 4) / (s ** 4)).sum() ) - ((3 * (n-1) ** 2) / ((n-2) * (n-3)))

```

np.random.randn(100)で作成した標準正規分布のデータで調べたらほぼ0になったので、多分あってるはずです(笑)

# 参考

歪度、尖度の計算式

https://bellcurve.jp/statistics/course/17950.html
【#9 エンジニア転職学習】Linux基礎　正規表現

# はじめに
富山県に住んでいるChikaといいます。
毎日投稿を目標に、バックエンドエンジニア転職に向けた学習内容をアウトプットします。

連日になりますが、Linuxの基礎を進めましたので自分なりに気になったポイント等をまとめていきます。

バックエンドエンジニアになるまでの学習内容は以前投稿した以下の記事を基にしています。


https://qiita.com/Chika110/items/ef54dddd565a0193ef44

# 本日の学習内容
本日は正規表現の基礎をやりました。DBの部分でも学習範囲としてあった気がするので概要と基本的な部分が学べてよかったです。

* grep
* **正規表現・メタ文字　←Topic!!**

# 正規表現・メタ文字
正規表現とは「条件に合致する文字列集合を表現するための記法」のことらしいです。基本正規表現（デフォルト）と拡張正規表現（grepでは-Eオプション）があり、その名の通り拡張のほうができることが多いようです。

メタ文字とは「正規表現で使用される特別な意味を持つ記号」のこと。以下メタ記号に関するメモになります。
* \でメタ文字を打ち消す（エスケープする）
* 連続使用OK
* [a-k]のように範囲指定もOK
* （）で囲うことで単語単位で繰り返し指定ができる


使用している書籍はこちら↓

https://www.amazon.co.jp/%E6%96%B0%E3%81%97%E3%81%84Linux%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E4%B8%89%E5%AE%85-%E8%8B%B1%E6%98%8E-ebook/dp/B072K1NH76/ref=sr_1_1?adgrpid=113196705062&gclid=Cj0KCQjwzLCVBhD3ARIsAPKYTcR4WAb_4QVrwuBM_1mIPMFsQ6kNDJ-o4yIofVSAI7_eHpWCeva8kKwaAstgEALw_wcB&hvadid=489559881279&hvdev=c&hvlocphy=1009363&hvnetw=g&hvqmt=e&hvrand=10125867468998217428&hvtargid=kwd-1152146940662&hydadcr=21814_10996132&jp-ad-ap=0&keywords=%E6%96%B0%E3%81%97%E3%81%84+linux+%E3%81%AE+%E6%95%99%E7%A7%91%E6%9B%B8&qid=1655473534&sr=8-1




# おわりに
最後までお読みいただきありがとうございました。
明日も引き続きLinuxの基本を進めていこうと思います。
アドバイス・応援コメント等いただけますと幸いです。
laravel API とりあえずPostManとかから値を投げられるようにする

# 概要

- laravelをAPIサーバーとして使う際にとりあえずPostManとかでリクエストボディー込で投げてオウム返しするように設定する方法をまとめる

# 方法

1. ルーティングの記載
    1. 下記のようにapi.phpのルーティングファイルにルート情報を記載する。

        ```アプリ名ディレクトリ/routes/api.php
        <?php
        
        declare(strict_types=1);
        
        use App\Http\Controllers\ContentController;
        use Illuminate\Support\Facades\Route;
        
        /*
        |--------------------------------------------------------------------------
        | API Routes
        |--------------------------------------------------------------------------
        |
        | Here is where you can register API routes for your application. These
        | routes are loaded by the RouteServiceProvider within a group which
        | is assigned the "api" middleware group. Enjoy building your API!
        |
        */
         
        Route::post('/return', [ContentController::class, 'return'])->name('return');
        ```

1. コントローラーの記載
    1. 任意のコントローラーを定義して、下記のように記載する。

        ```アプリ名ディレクトリ/app/Http/Controllers/ContentController.php
        <?php
        
        declare(strict_types=1);
        
        namespace App\Http\Controllers;
        
        use Illuminate\Http\Request;
        
        class ContentController extends Controller
        {        
            public function return (Request $request)
            {
                return $request;
            }
        }
        ```

1. `/api`ルーティングのCSRF回避
    1. `アプリ名ディレクトリ/app/Http/Middleware/VerifyCsrfToken.php`を開き下記のように`/api`のルートのみCSRFのチェックを無効化する。

        ```アプリ名ディレクトリ/app/Http/Middleware/VerifyCsrfToken.php
        <?php
        
        declare(strict_types=1);
        
        namespace App\Http\Middleware;
        
        use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;
        
        class VerifyCsrfToken extends Middleware
        {
            /**
             * The URIs that should be excluded from CSRF verification.
             *
             * @var array<int, string>
             */
            protected $except = [
                '/api',
            ];
        }
        ```

1. あとは任意のリクエストボディーを記載してPostManなどで`http://localhost/api/return`にPOSTメソッドでリクエストを送れば送ったJSONをそのままオウムがえししてくれるはず。（http://localhostの部分は適宜皆さんの環境に合わせて変更してください。）
1. バリデーションのチェックもしたいなどあれば下記を参考に独自のリクエストクラスをお作りいただき、バリデーションエラーがJSONで返るように設定すればOK
    - [laravel API バリデーションエラー時にエラー内容をJSONで返す](https://qiita.com/miriwo/items/637961702389d6673489)
Robocode Tank Royale Debugの仕方

ちょっと番外編的に、Robocode Tank Royale におけるDebugの仕方

もちろん書いてはあるのですが、ちょっと理解に時間がかかったので。

https://robocode-dev.github.io/tank-royale/articles/debug.html#supply-a-server-secret

大まかには、
サーバを起動している状態で、
環境変数にserver secretを設定し、
ターミナルからbotを実行すると、
System.out.println　で出力できる。

ということです。書いてあるんですけどね。

例えば、WindowsのEclipseの場合、一つのターミナルで、

```
java -jar robocode-tankroyale-gui-0.13.2.jar
```

を実行しておきます。
さらに、このGUI画面のメニューから、erver > Start Server（もしくは、reboot Server）しておきます。

そして、そのフォルダに存在するserver.propertiesファイルの中を見ると

```
bots-secrets=xxx
```

と書かれている行があります。このxxxを使って、

```
set SERVER_SECRET=xxx
```

という文字列を作ってコピーしておきます。

もう一つターミナルを起動し、開発中botのフォルダに移動し、上記を実行後、botを実行します。

```
cd JayBot
set SERVER_SECRET=xxx
java -cp ../lib/* JayBot.java
```

そうすると、start battleのbot選択画面で、上部の選択をしなくても、下部の一覧に開発中botが表示されます。
これを選択して戦闘開始することで、ターミナルに出力されることになります。

robocode画面のServerLogは関係ないです。

というわけで、開発を続けます！
10％はバッファを取れ。「仕様変更」は必ず起きる。

「良いプロへジェクトは早く終わりましたを聞く」の適切なバッファについて。第三回。最終回です。
第一回では[バッファののないプロジェクト](https://qiita.com/satou_ot/items/731158951e951a1e2851)が、どんなに無謀で無計画かを説明しました。
第2回では[バッファの必要な原因はなにか？](https://qiita.com/satou_ot/items/c3ac2fdfc6c8c40423db)を探るため統計的を用いてバッファが何のためにあるのかを考えて。仕様変更は76.9%とほぼ8割のプロジェクトで起こることを検討しました。
第3回はこれらを踏まえて「適切なバッファ」の考慮をします。
なお以下の資料は引き続き「一般社団法人日本情報システム・ユーザー協会　ソフトウェアメトリックス調査2020」を使用しています。

# 仕様変更はスケジュールだけでなく全体の質を下げる
下記の図を見てみましょう。仕様変更の重要度で工期遅延する割合がよくわかります。
「仕様変更がない」プロジェクトが75%成功するのに対して、「重大な変更」が合った場合には、工期は3割も守られません「ほぼ失敗する」と確定していいくらいになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/1e2e538d-c121-8685-57ac-25c98a3fb575.png)

納期という観点の失敗だけではなく、品質や機能性、顧客や開発に携わった人々の満足度全てが低下しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/3a23ad16-cc3a-b560-9842-b469422cef62.png)

# 適切なバッファとは？
幸い我々には実際にそうしたプロジェクトの結果を分析し、予め80%の確率で起こる仕様変更に備えることが出来ます。
JUASの資料で検証対象となるような”ある程度の規模”のプロジェクトの半数（52.6%）が総予算の10%を設定していることと
実際に仕様変更が発生した76%のプロジェクトの超過コストが9.3%であることから

**総予算の10%がバッファの目安**といっていいことになります
これは費用だけの話ではなく。スケジュール等他のリソース全てに当てはまります。
人員や、サーバーリソースなど、あらゆるリソースに10%プロジェクトが膨らんでもいい余裕
を持たせておく必要があります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/cc46b7b8-c925-b64a-e992-3cfe41fcce65.png)

# 「早く終わりました」を聞くためには
「仕様変更は必ずと言っていいほど起こり。そして必ずと言っていいほど計画に影響する」事実を踏まえ。
見積もりやプロジェクト計画、リソース計画にバッファが必要であることを、開発チームだけではなく、ステークホルダー全体。発注者や会社組織全体で理解しましょう。

其の上で、これまでの多くのプロジェクト実績から少なくとも「総リソースの10%」をバッファとして用意しましょう。
勿論、この想定はプロジェクトの難易度や。チームの練度。発注側の要件定義体制の密度など、様々な要素に左右されます。
ですが「少なくとも10%」を確保しておくことで、飛躍的に成功確率は上がるといえます。

ぜひ、「早く終わりました」という報告をプロジェクトミーィングで聞き。
余裕を持ってビジネス運用を構築したり。
早くテストリリースして非機能要件のテストに当てたり。
より良いプロジェクトを運営できるように取り組みましょう。

最後にCMです。見積もりはプロジェクトの「初期計画」です。ぜひ本書を読んで取り組んでください＾＾
[システム開発のための見積りのすべてがわかる本](https://www.shoeisha.co.jp/book/detail/9784798156491)
laravel API バリデーションエラー時にエラー内容をJSONで返す

## 概要

- laravelをAPIサーバーとして使う際にバリデーションエラーのエラーメッセージをJSONで返す方法をまとめる。
- 昔記載した下記の記事のリバイバル版の内容です。
    - [Laravel API データポスト時のバリデーションで弾かれた後、http://127.0.0.1:8000/にリダイレクトしてしまう](https://qiita.com/miriwo/items/976a25a31550973e73b8)

## 方法

1. FormRequestクラスを継承した独自のリクエストクラスを作成する。
1. 任意のバリデーションルールを記載する。
1. 独自のリクエストクラスに下記の内容を追記する。

    ```php
    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Contracts\Validation\Validator;

    protected function failedValidation(Validator $validator)
    {
        $response['errors']  = $validator->errors()->toArray();

        throw new HttpResponseException(response()->json($response));        
    }
    ```

1. 一例だが、独自のリクエストクラスに上記内容を追記した場合下記のようになる。

    ```ContentRequest.php
    <?php
    
    namespace App\Http\Requests;
    
    use Illuminate\Foundation\Http\FormRequest;
    use Illuminate\Http\Exceptions\HttpResponseException;
    use Illuminate\Contracts\Validation\Validator;
    
    class ContentRequest extends FormRequest
    {
        /**
         * Determine if the user is authorized to make this request.
         *
         * @return bool
         */
        public function authorize()
        {
            return true;
        }
    
        /**
         * Get the validation rules that apply to the request.
         *
         * @return array
         */
        public function rules()
        {
            return [
                'array' => ['sometimes', 'required', 'array', 'min:1'],
            ];
        }
    
        protected function failedValidation(Validator $validator)
        {
            $response['errors']  = $validator->errors()->toArray();
        
            throw new HttpResponseException(response()->json($response));        
        }
    }
    ```
DM機能実装する時に使用できるサイト

★非常にわかりやすく且つシンプルで理解しやすいのでオススメです！

https://qiita.com/mi-1109/items/660ec3630e76f11d1f16


★実装はできなかったけど、わかりやすい感じでした！

https://qiita.com/bindingpry/items/6790c91f374acc25bea2
【GCP】Google Cloud Skills Boostを受講してみた

# はじめに

**Google Cloud Skills Boost**とはGoogle Cloud Platform (GCP)が提供するハンズオンオンライン講座です。6月2日から「みんなで学ぼう Google Cloud 〜 オンライン体験プログラム 〜」というイベントが開催され、これに参加すると無料で1ヶ月GCPを触る事ができ、GC Skills Boostの講義も受講できる様なので参加してみました。そして受講したのがこちらの3つ。ひとつひとつ紹介します。<a href = "https://www.cloudskillsboost.google/public_profiles/a8d59743-825b-41fe-9fb5-88f282918706">修了証明書</a>。

・**Create and Manage Cloud Resources**
・**Predict Soccer Match Outcomes with BigQuery ML**
・**Perform Foundational Data, ML, and AI Tasks in Google Cloud**
![Screen Shot 2022-06-23 at 19.34.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1044781/a3091611-25ed-d2ff-e674-ec7caa05d9ac.png)


# Create and Manage Cloud Resources 
以下の説明文にもある様にGCPの機能を一通り体験できる講座です。インスタンスを作成し、サーバーやCPUなどのスペックを設定し仮想マシンをデプロイの手順を確認できます。要はイントロダクションコースです。まず初めに手を付けるならここからですね。受講ページは<a href = "https://www.cloudskillsboost.google/quests/120?catalog_rank=%7B%22rank%22%3A3%2C%22num_filters%22%3A0%2C%22has_search%22%3Atrue%7D&locale=ja">こちら</a>。

> 【概要】
推定学習時間：5時間
Google Cloud の基本的なツールやサービスに関する実践演習を行います。クラウドの予備知識がほとんどなくても、 あらゆる Google Cloud プロジェクトに応用できる実際的な経験を積めるます。Cloud Shell コマンドの記述、初めての仮想マシンのデプロイ、Kubernetes Engine 上でのアプリケーション実行と負荷分散など、Google Cloud の主な機能を紹介します - GCP(一部省略)


# Predict Soccer Match Outcomes with BigQuery ML　 
BigQueryとGCP標準装備の機械学習ライブラリを使いサッカーの試合の結果を予測しました。GCPに格納されているのサッカーデータ（CSVとJSON）をマッシュアップして、シュートが打たれた座標やゴールとの距離や角度、その日のグランドのコンディションのデータから、そのシュートが決まる確率などを算出しました。使ったモデルはロジスティック回帰でした。BigQueryは触った事がなかったのでなかなか面白かったです。シュートデータだけではなく、パスやフリーキック、ファウルのデータも盛りだくさんだったので、スポーツデータ好きな方はぜひ触ってみてください。受講ページは<a href = "https://www.cloudskillsboost.google/quests/204?catalog_rank=%7B%22rank%22%3A1%2C%22num_filters%22%3A0%2C%22has_search%22%3Atrue%7D&locale=ja&search_id=17281938">こちら</a>。

> 【概要】
推定学習時間：5時間
CSV ファイルや JSON ファイルをインポートして BigQuery でサッカー データセットを作成する方法、BigQuery ML を使用してサッカー イベントのデータに対して予想ゴール モデルをトレーニングする方法、ワールドカップのゴールの印象を評価する方法など、BigQuery を使用したスポーツ データサイエンスの基礎について実践的な経験を積むことができます。- GCP(一部省略)


# Perform Foundational Data, ML, and AI Tasks in Google Cloud 
上記のPredict Soccer Match Outcomes with BigQuery MLラボで行ったBigQueryのデータ処理と、Apache Spark や Python を使いデータ加工を自動化するJobの作成から始まり、音声ファイルや動画ファイルといった非構造化データにも手を出す講座です。非構造家データは専門ではないので少し戸惑いながらも修了。NLP、画像処理APIを使いファイル転送すると分析結果が帰ってくる仕様でした。実装方法はよく分かったのですが、分析手法やモデルについての説明は少なかった（なかった？）気がしました。あくまでGCPの使用方を学ぶ講座なのでしょう。受講ページは<a href = "https://www.cloudskillsboost.google/quests/117?catalog_rank=%7B%22rank%22%3A1%2C%22num_filters%22%3A0%2C%22has_search%22%3Atrue%7D&locale=ja&search_id=17282147">こちら</a>。



> 【概要】
推定学習時間：7時間
BigQuery、Cloud Speech API、AI Platform などの最初のステップを学び、ビッグデータ、機械学習、AIの活用術を学事ができます。- GCP


# おわりに
「みんなで学ぼう Google Cloud 〜 オンライン体験プログラム 〜」で無料でGCPが触れてラッキー！今後この様なイベントがたくさんありますように！！
【Django】タイムゾーン修正方法

## Djangoのタイムゾーンを日本に変更する方法

デフォルトではUTCが設定されているため、
日本に変更する必要がある

## settings.pyを修正する

設定方法は、settings.pyを修正することで可能です。

対象は以下文言です

```python
LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'
```

以下に修正します

```python
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

## 適用確認

```python
python manage.py shell
```

shellを起動し、現在時刻を確認します

```python
以下ファイル修正前
In [1]: from datetime import datetime

In [2]: print(datetime.now())
2022-06-13 12:43:06.603059

以下ファイル修正後
In [1]: from datetime import datetime

In [2]: print(datetime.now())
2022-06-13 21:44:31.749582
```

時刻が正しいものに変わっていることがわかります

以上です。
laravel 配列の中に最低一個の要素が入っていてほしい場合のバリデーション

# 概要

- バリデーションルールを組み合わせて「配列の中に最低一個の要素が入っている場合OK」とするバリデーションルールを考えてみる。

# 詳しいルール

- リクエストボディーに`array`のキーがあった場合のみ後述するルールをチェックしてほしい。
- `array`の値は必須
- `array`の値は配列型
- `array`の配列の中に最低一個の要素がある（0個はNG、一個以上ならいくつでもいい）

# 実際の記載

- 下記のようにFormRequestクラスに記載してバリデーションルールを定義してみた

    ```FormRequest.php
    /**
     * Get the validation rules that apply to the request.
     *
     * @return array
     */
    public function rules()
    {
        return [
            'array' => ['sometimes', 'required', 'array', 'min:1'],
        ];
    }
    ```

- ルールの詳細
    - `sometimes`: 「キーがあった場合、それ以外のバリデーションルールをチェックする。キーが無かったらそれ以外のバリデーションルールはスルーする」
    - `required`: 「必須」
    - `array`: 「配列型」
    - `min:1`: 「最低一個」
- minルールの指定を変更すれば「最低何個」の部分を変更する事ができる。

# 参考文献
- [https://qiita.com/miriwo/items/cf3518caf5a8da110c52](https://qiita.com/miriwo/items/cf3518caf5a8da110c52)
- [https://kojirooooocks.hatenablog.com/entry/2019/08/24/034111](https://kojirooooocks.hatenablog.com/entry/2019/08/24/034111)
【Flutter】IntelliJを使ってiPhone実機で実行したい

# やりたいこと
タイトル通りIntelliJを使ってFlutterのアプリをiPhone実機で実行できるようにしたい。

iPhoneとPCを繋げて、デバイスをつなげているiPhoneを選択している状態で、
普通に`Run　'main.dart'`で実行すると失敗してしまう。
![IMG_3811.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/120480/63df8981-9627-4e8e-c587-07aff77b4466.png)

# 解決
Relese modeで実行する必要がある。
`Run > Flutter Run 'main.dart' in Release Mode`で実行すると成功する。
Iteratorパターン（TECHSCORE読書会）

# 目的
ちゃんと勉強していなかったデザインパターンを学習したい。
TECHSCORE様のまとめ（何度か3日坊主に）を読み切りたい。

# 本日のページ
https://www.techscore.com/tech/DesignPattern/Iterator/Iterator1

# Iteratorパターンとは
* Listの各要素にアクセスする方法を提供するためのパターン
* 要素の捜査方法を与えるクラスをListとは独立させておく

# サンプルケース
## 学校の先生で生徒の名簿を扱う
学校から支給されたStudentListクラスを自由に拡張して利用することができるものとする。
以下を先生に求める能力と定義する。
1. 先生は、学校から与えられた名簿に自分の生徒を書き込むことができる
1. 先生は、生徒の名前を名簿の記載順に呼ぶことができる

## StudentList型の変更
StudentListを直接拡張すると、StudentListが急に変更になった際に、大きな影響を受ける。

# Iteratorパターン
## Iteratorパターンとは
* Iteratorパターンでは、何らかの集合体がAggregateインタフェースを実装する（Aggregateとは、集約を意味する単語）
* Aggregateインタフェースは、Iteratorインタフェースの実装クラスを返す
* Iteratorインタフェースでは、次の要素が存在するかしないかをboolean型で返すhasNext()メソッドと、次の要素を返すnext()メソッドを定義する。

## サンプルケースの解決
集合体が変わっても、構造は影響を受けない。
【PHP基礎⑯】ループ処理の終了－do…while文

［問題］　　(参照：http://www.cc.kyoto-su.ac.jp/~mmina/bp1/hundredKnocksBasic.html)
整数値を入力させ、入力値が0でなければ値を表示かつ再度入力してループ処理を続け、0であれば終了するプログラムを作成しなさい。


# コード
```php
do{
    $a = intval(fgets(STDIN));
    echo $a, PHP_EOL;
}while($a <> 0);
```

↓↓↓

5 
-6
0
1　　と入力

↓↓↓

# 結果
```
5
-6
0
```

☆do…while文
指定した条件がどうであれ、初回は必ず実行するという繰り返し処理。
2回目以降は、条件を満たす限りずっと処理を繰り返す。

$a = ○　←　初期値。あれば入れる。
do{
　条件を満たす場合に行う処理;
　増減式;　　←　あれば入れる。
}while(条件)
長方形の画像を正方形にする方法

## はじめに
長方形の画像を正方形にする機会があったので、実現方法を残しておこうと思います。
今回はやりたいこととして、元の長方形の画像から縦横の比率を崩さず正方形にしたかった（強引にリサイズして正方形にはしたくなかった）ので、長方形の画像に余白を付け足すことで正方形にする方法を取りました。
また、正方形にすると同時に指定のサイズへ変換をかけたかったため、リサイズも行っています。

## 実現方法①（OpenCVを利用する）
OpenCVという画像処理系のライブラリを使用することで実現しました。（言語はJavaで実装）

``` Java
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class ImgConv {
    static{
        // DLLのロード
        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
    }

    public static void main(String[] args) {
        String img_in = "C:/hogehoge.jpg";
        String img_out = "C:/fugafuga.jpg";
        // 処理対象の画像を読み込む
        Mat mat_in = Imgcodecs.imread(img_in);
        Mat mat_out = new Mat();

        // 上下に60pxずつ余白を追加し、RGBで色の指定を行う
        Core.copyMakeBorder(mat_in,mat_out, 60, 60, 0, 0, Core.BORDER_CONSTANT,new Scalar(255,0,0));
        // 300x300にリサイズする
        Imgproc.resize(mat_out, mat_out, new Size(300,300));
        // 処理した画像の出力
        Imgcodecs.imwrite(img_out, mat_out);
    }
}
```

## 実現方法②（ImageMagickを利用する）
ImageMagickを利用して実現しました。
今回はWindowsで正方形を作成しましたが、Linuxでも同様に可能です。

``` shell
# Linuxの場合は先頭のmagickは不要
magick convert "hogehoge.jpg" -mattecolor "#fff" -frame 0x60 "fugafuga.jpg"
magick convert -resize 300x300 "fugafuga.jpg" "fugafuga.jpg"
```
xargsコマンドの使用方法

使い方がわからなかったため自分で調べたものをアウトプットしてみます。
間違っている事があればぜひ教えていただきたいです。
便利なコマンドなども教えていただきたいです！

### xargsコマンドとは

標準入力やファイルからリストを読み込み、コマンドラインを作成して実行するコマンド

```:書式
コマンド1 | xargs コマンド2
```

```:使用例
find . -name “*.txt” | xargs rm -fv
```

※　-f 存在しないファイルを無視する -v 経過を表示する



### 「 | 」パイプとの違いについて

パイプだけでいいのではないかと思っていたので違いを書いてみました。
test1.txtとtest2.txtのそれぞれのファイルにnekoとinuを追記

```:検証してみました
xargsの場合
ls test*.txt | xargs cat
neko
inu

xargsなしの場合
ls text*.txt | cat
test1.txt
test2.txt
```

出力結果は違いました。
なぜかというと↓

 | xargs：左側のコマンドの標準出力を右側のコマンドの引数に指定する

 |：左側のコマンドの標準出力を右側のコマンドの標準入力に入力する


xargsコマンドは何かと便利なようなので使いこなせるようになりたいです！
【SwiftUI】外観モードを検知する

# 公式ドキュメント
https://developer.apple.com/documentation/swiftui/colorscheme

# 使い方
```swift
import SwiftUI

struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme
    var body: some View {
        Text(colorScheme == .dark ? "Dark" : "Light")
    }
}
```

# おわり
システムのカラースキームとは別のカラースキームをアプリ内で使用したい場合は少し工夫が必要になります。
以下の記事がとても参考になりました。

https://qiita.com/MaShunzhe/items/e0b5cab0df689438379f
Google の拡張機能 ModHeader で PC のブラウザ上で smartphone の画面に切り替える方法

# はじめに
Google の拡張機能、ModHeader の使い方についてです。
smartphone のヘッダーをつけることを例に解説します。

# ModHeader とは？
HTTP ヘッダーをブラウザ上で付与することができます。
例えば、curl で表現すると
```
curl -H "jwt-token: ey~" "http://example.jp/"
```
のような jwt-token などのヘッダーをつけた状態で、ブラウザ上でアクセスしたい場合などに役立ちます。
今回は PC ブラウザ上で smartphone アプリと同様の表示にしたい場合の操作方法です。

# ModHeader を導入
以下のサイトにアクセスします。
https://chrome.google.com/webstore/detail/modheader/idgpnmonknjnojddfkpgkljpfnnfcklj?hl=ja

以下の画像のようなページに入りますので、Chrome に追加ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/c06409fb-dd96-2afc-5d65-242fd47db7ad.png)

画像のようなポップアップが表示されたら完了です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/7348e398-3376-7261-f7b7-d2d4533624cb.png)

# ModHeader の操作
Chrome の右上にパズルみたいな表示があると思うので、そちらをクリックします。
こんな感じ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/6d27e3de-edcf-f1f2-9fc3-dba5846c409e.png)
ModHeader をクリックすると画像のように Name, Value を指定できる画面になるかと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/d7295dc1-0a26-9658-fa02-d9bfcedaf9ce.png)
そしたら以下のように入力してください。
|Name|Value|
|-|-|
|x-devcat-category|smartphone|

リロードすると smartphone の画面になるかと思います。
例えば [Yahoo finance](https://finance.yahoo.co.jp/)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/b7a9798c-8686-7875-8be5-3113ea6b09ba.png)
# 設定を戻したい場合
Pause ModHeader と出てる部分をクリックすると、設定を消さずに元に戻すことができます。（要リロード）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/477044/bfe6edb1-24d9-b2aa-5adf-8b6ab697ada2.png)
基本情報（CPUの高速化技術）

本の内容と自分が知っている業務で出てきた処理の内容が頭の中で混乱してしまったので
基本情報とは別に記述しようと思います。


## 逐次制御方式
```
命令１　A→B→C→D
命令２　　　　　　　　　　　　　　　　A→B→C→D
命令３　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　　A→B→C→D

A 命令の取り出し
B 命令の解読
C 対象データ読み出し
D 命令実行
```
命令１が終わったら後に命令２に移行します。一つの処理が終わったら次の処理に移ります。

## パイプライン処理

```  
     1 2 3 4 5 6 7 8 9 10 11 12 
命令1 A→B→C→D
命令2　　　　　　　　　　　　　  A→B→C→D
命令3　　　　　　　　　　　　　　　　　　　　　　　　　　　　　   A→B→C→D
---------------------------
12クロック
     1 2 3 4 5 6
命令１　A→B→C→D
命令２　　　　　A→B→C→D
命令３　　　　　　　　　A→B→C→D
---------------------------
6クロック
```
命令実行手順の各段階のことを**ステージ**と呼びます。
上記は1つのステージを１クロックで処理できるCPUだと仮定しています。

６クロックで処理した方をパイプライン処理と呼びます。

## 分岐予測と投機実行
```
命令3 →　命令４
　　　　　　　　　　　→　命令５
```
上記のような命令の際に、命令４に行くか命令５に行くか分岐の結果がわからないと、次の命令の処理を開始することができません。

そこで、この分岐が実施されるのか、その場合の次の命令をどれかを予測することで無駄な待ち時間を生じさせないようにします。これを**分岐予測**といいます。

予測に基づいて分岐先の命令を実行する手法を**投機実行**といいます。

## スーパーパイプラインとスーパースカラ
パイプライン処理による高速化を進める手法としてスーパーパイプラインとスーパースカラがあります。

スーパーパイプラインは各ステージの中身をさらに細かいステージに分割することで、パイプライン処理の効率アップを図るものだそうです。
簡単にいうとパイプラインを更に細かくしたイメージですね。
```
命令１ A¹A²A³→B¹B²B³→C¹C²C³→D¹D²D³
命令２ ↓ A¹A²A³→B¹B²B³→C¹C²C³→D¹D²D³
命令３   ↓ A¹A²A³→B¹B²B³→C¹C²C³→D¹D²D³
```

並行して処理できる範囲が増えたので効率がアップします。

スーパースカラはパイプライン処理を行う回路を複数持たせることで、まったく同時に複数の命令を実行できるようにしたものです。
```
命令1 A→B→C→D
命令２ A→B→C→D
命令３   A→B→C→D
命令４   A→B→C→D
```
同時に複数のパイプラインを走らせます。


## CISCとRISC
CPUのアーキテクチャの話になります。
CPUには高機能な命令を持つCISCと単純な命令のみで構成されるRISCという2つのアーキテクチャがあります。

**CISC(Complex Instruction Set Computer)**
CISCはCPUに高機能な命令を持たせることによって、ひとつの命令で複雑な処理を実現するアーキテクチャです。

特徴は下記です。
```
・　マイクロプログラムを内部に記憶させることで高機能な命令を実現できる
・　命令の追加や変更が容易
・　便利な命令がそろっているので、機械語のプログラム作成がラク
・　命令の実行速度は遅い
・　命令の長さや実行速度がバラバラ
```

**RISC(Reduced Instruction Set Computer)**
RISCはCPU内部に単純な命令しか持たない代わりに、それらをハードウェアのみで実装して
ひとつひとつの命令を高速に処理するアーキテクチャです。
```
・　ワイヤードロジックによって全ての命令をハードウェア的に実装
・　命令の追加や変更は難しい
・　単純な命令があるだけなので手作業による機械語のプログラム作成は困難
・　命令の実行速度が速い
・　命令の長さや実行速度がほとんど等しい
```

## まとめ
CPUの中でも細分化されて様々な処理が走っていることがわかりました。
中身を知っていることは業務で行っているプログラミングの理解にも影響するので
基本情報の内容はしっかりと覚えていきます。
[自分用]CockpitをCentOS7にインストールする[完全版]

# はじめに

　この記事はあらゆる確認のためにCentOS7を再インストールするたびにCockpitをインストールしなおすのに、コピ＆ペ、コピ＆ペ、コピ＆ペといちいち繰り返すのがめんどくさくなったため、コマンドをまとめてしまおうと書いている記事です。つまり備忘録だとか、チートコードだとか、そういう類のやつです。
　いるかどうかは分かりませが、いる人がいれば便利に使ってやってください。

# cockpitとは！
　LinuxをWebインターフェースで監視、管理することの出来るシステムです。
　初期段階ではCPUやメモリ使用量をグラフで可視化してくれたり、エラーログなどログを確認できたり、ネットワークの接続状況だとかファイアウォールの設定だとかを確認できたり、アカウント管理・サービス管理がGUI的に出来たりします。
　また、ここが一番面白かったところですが、sshの代わりにもなります。
　他追加機能はアドオンをインストールすることで出来ますし、何なら自分で作ることも出来たりします。

# 環境
**2022/06/23**
・Linux CentOS7
・cockpit 195.12.

# コマンドs

```
sudo yum -y install cockpit
sudo systemctl start cockpit
sudo systemctl enable cockpit.socket
sudo systemctl start firewalld.service
sudo systemctl enable firewalld.service
firewall-cmd --add-port=9090/tcp --permanent
firewall-cmd --remove-service=ssh --zone=public --permanent
firewall-cmd --reload
sudo yum install -y cockpit-docker
sudo yum install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.8/cockpit-navigator-0.5.8-1.el7.noarch.rpm
```

　sshは閉じています。
　dockerのイメージ管理のアドオンを追加しています。
　Navigatorのアドオンも追加しています。ただしNavigatorのアドオンはバージョン違いがあると思いますので、場合によってインストールしたりしなかったりしてください。

### Navigatorのインストール

　GitHubのInstallationから、(自分が使用しているOSが)CentOS7なのでEL7のコマンドをコピ＆ペーストしてきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2647158/7534c62e-5bb3-f487-4e0a-c3146eb78e70.png)


```
sudo yum install https://github.com/45Drives/cockpit-navigator/releases/download/v0.5.8/cockpit-navigator-0.5.8-1.el7.noarch.rpm
```

https://github.com/45Drives/cockpit-navigator
破棄したはずのSessionが残っている？？

 入力フォームを作っているときにハマったのでメモ

## 想定している状況
* 入力フォームで入力した情報を登録する
    * 入力した情報はセッションで管理する

<details><summary><b>プログラム</b></summary><div>

```Hogehoge.java
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

@WebServlet("/hogehoge")
public class Hogehoge extends HttpServlet {
    private static final long serialVersionUID = 1L;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 省略
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 文字コードを指定
        req.setCharacterEncoding("utf-8");

        // リクエストからセッションを取得
        HttpSession session = req.getSession(false);

        // 二回目以降のアクセスをできなくするためにセッションの有無を確認する
        if (session == null) {

            // 二回目以降のアクセスなら別の画面(fugafuga)へ遷移
            req.getRequestDispatcher("/fugafuga.jsp").forward(req, resp);

        } else {
            // 登録する値を取得
            String xxxxxx = (String) session.getAttribute("xxxxxx");

            // 登録する処理（省略）

            // 登録後の画面(hogehoge)へ遷移
            req.getRequestDispatcher("/hogehoge.jsp").forward(req, resp);
            
            // セッションを全て破棄する
            session.invalidate();
        }
    }
}

```

```fugafuga.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>fugafuga</title>
    </head>
        <body>
            登録完了しました。
        </body>
</html>

```

</div></details>

### やりたかったこと
* 複数回の登録を防ぐために、登録後はセッションを破棄する
* F5などで再度ページが読み込まれた場合は、別のページ(jsp)に遷移する

### 実際におこったこと
* F5などで再度ページが読み込まれたとき、一度目は別のページ(jsp)に遷移する
    * その後セッションが新たに作られてしまい、二度目はセッションが存在するときの挙動になってしまう

# 解決方法①
JSPに以下を記述しよう！
```.jsp
<%@ page session="false"%>
```

## 解説



上記のプログラムだと一度目の再読み込みではきちんとfugafugaに遷移するが、
二度目の再読み込みではhogehogeへ遷移してしまう。

<b>原因はjspにある。</b>

<b>jspでsession属性の指定を省略すると、session="true"が設定されたものと見なされて勝手にセッションがつくられてしまう。</b>

```fugafuga.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
```

そのため、以下のように書かないと、セッションが新たに作られてしまうのである。
```fugafuga.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" session="false"%>
```

# 解決方法②

条件式を変えてしまおう！
```Hogehoge.java
//if(session != null){
if(session.getAttribute("xxxxxx") != null){

}
```

## 解説

新しいセッションは勝手に作られるが、セッションのattributeはもちろん削除されているからである。
ただ新しいセッションが残り、無駄にメモリが消費されるので可能な限り①を推奨する。

# 結論
JSPでは何も書かないと勝手にHTTPセッションを作成する。
それを知らないとセッションが存在しているかどうかの条件分岐で困ることになるので注意。
また、アプリケーションサーバ上のメモリが無駄に消費されるので、セッションが不必要ならばJSPに以下を記述するべし。
```.jsp
<%@ page session="false"%>
```