OmniAICreator/Qiita-1.07M huggingface dataset:
自作音ゲーの譜面データについて悩む

#結論
とりあえず今回はテキストデータと譜面データとして使用したいので↓の中から知っていて使いやすそうなcsvで対応させることにしました
>.txt
.html
.htm
.xml
.bytes
.json
.csv
.yaml
.fnt
[Unity テキストアセット](https://docs.unity3d.com/ja/2019.4/Manual/class-TextAsset.html)



#前提
音ゲーはノーツと呼ばれる判定を音楽を聴きながらリズム良く押すことによって得点が加算されていきます

ノーツを呼び出すタイミングを記したファイルを譜面データと言います
譜面データにはノーツのタイミングの他にノーツの種類や、速度などを埋め込んだりします

#タイミングについて
タイミングを呼び出す方法は2種類あると思います
時間指定か小節指定です
※他にもありそうだったらコメントください

#小節指定のjson
最初は小節指定のjsonファイルを作ろうと考えていました

```json
notes{
[[ノーツの種類,ノーツのレーン,速度][ノーツの種類,ノーツのレーン,速度]]//1小節目
[ノーツの種類,ノーツのレーン,速度]...//2小節目
}

```

のように生成しようとしていました

##メリット
・小節ごとの管理が楽
##デメリット
・bpmが変わる曲は作りにくい

##何故使わなかったか
jsonファイルをforやforeachで回すのが難しかった

jsonは[key:value]のように値が存在しており

```json
{notus:
[key:value,key:value],
[key:value,key:value],
[key:value,key:value]}

```
のように作ることができます
valueを取り出してノーツを生成します

```C#
//jsonファイルの読み込み
var textAsset = Resources.Load("譜面.json") as TextAsset;

var jsonText = textAsset.text;
JsonNode json = JsonNode.Parse(jsonText)

//jsonを辞書に入れる
Dictionary<string,object> dic_json = json["notes"].Get<Dictionary<string,object>>();
foreach (var notes in json["notes"])
{
    long note = notes["note"].Get<long>();
    for (int i = 0; note > i; i++)
       //インスタンスからノーツを生成
    }
}
```
※うろ覚え
これの悪い点は`note`に入っている総ノーツ数がずれるとノーツの呼び出しがされなくなること
また、foreachで変数に追加して呼び出すと

```console
[0:1,1:1,2:2]
```
のようにリストで出てくるので割とめんどくさい
そして、ここではJsonNodeを使ってますが、Unity標準のJsonUtilityを使うと型を作らないといけないので音ゲーのようなデータの最大量が変わるものには向いてません




#時間指定のCSV
csvは０行目に曲情報、その後ろにノーツ情報を追加しました
ノーツの情報の詳細は

```
ノーツの種類(番号),ノーツのレーン,ノーツが来る時間,ノーツの速度(元bpm* 基本的に1)
```
です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/374827/b51d1f27-0641-a5ac-fbfc-e33198306350.png)

##メリット
・実装が簡単
・拡張性がある

##デメリット
・譜面制作の難易度が激ムズ



```C#
//ファイル読み込み
csv_read("../譜面.csv");

music_name = csvDatas[0][0];
bpm = float.Parse(csvDatas[0][1]);
all_notes = int.Parse(csvDatas[0][2]);
offset = double.Parse(csvDatas[0][3]);
//インスタンスをリストに追加
GameObject_all_notes.Add(new GameObject[]{ notes1, notes2, notes3, notes4, notes5 });
for (int i = 1; i < csvDatas.Count; i++)
{
    _type = int.Parse(csvDatas[i][0]);
    _lane = int.Parse(csvDatas[i][1]);
    _time = float.Parse(csvDatas[i][2]);
    _speed = float.Parse(csvDatas[i][3]);
    Generate =  GameObject_all_notes[int.Parse(csvDatas[i][0])][int.Parse(csvDatas[i][1])];
    
    Generate.GetComponent<notes>().set_up_notes(_time, _speed);
    Instantiate(Generate, new Vector3(Generate.transform.position.x, Generate.transform.position.y, Generate.transform.position.z + (_speed * public_speed * 10) * _time), Quaternion.identity);
}
```
これは現在使っているコード(の簡略版)
こちらは割と拡張性もあり簡単のノーツを生成することができるのでよき
ただし、インスタンスを生成する際にノーツのスピードとタイミングを計算しないといけないのでそこだけ注意

ついでにオブジェクトの加速度を切らないとだんだんズレます
PythonでAtCoder

#AtCoderでの使用言語をPythonに変更
先日AtCoderでの使用言語をC++からPythonに変更しました。
Pythonは初心者であるため仕様を忘れた際に自分で参照するためのメモを作成しました。
自分用なので説明などないですが公開したいと思います。

#標準入力

intで入力する場合

```python:a.py
a=int(input())
```

int行列リストで取得

```
n, m, k=map(int, input().split())
a=list(map(int, input().split()))
```

```
#入力
#B1 C1
#B2 C2
#⋮
#BQ CQ

bc=[]
for _ in range(q):
    a, b=map(int, input().split())
    bc.append((a, b))
```

文字列

```python
s=input()
```

#標準出力

リストを空白区切りで出力

```python
ans = [elem ^ 2 for elem in A]
print(* ans) 
```

小数点以下桁数指定

```python:
num = 123.456
print('{:.08f}'.format(num))
# => 123.4560000
```


#for文

```python
#for(int i=0;i<n;i++)
for i in range(n)

#for(int i=begin; i<n; i+=step)
for i in range(begin, n, step)

```

#文字・文字列操作

文字

```python
#Unicodeで整数iの文字を返す
c = chr(i)

#文字のUnicodeを返す
n = ord('a')
```

文字列

```python
#s="abcde"
s=input()

#i文字目にアクセス
s[2] = 'b'
# "abbde"

#リストの反転
s = s[::-1]
# "edbba"
```

#sort

```python
#昇順
p.sort()

#降順
p.sort(reverse=True)
```

#辞書

```python
#定義
cnt={}
if a not in cnt:
    cnt[a]=0
```

#論理演算子

```python
#OR
z = x | y

#AND
z = x & y

#XOR
z = x ^ y

#NOT
z = ~x
```

#MOD計算

nCkとnPk

```python
MOD = 10**9 +7
LIM = 1100000
fact = [1] * LIM
invfact = [1] * LIM

for i in range(1, LIM):
    fact[i] = fact[i-1] * i % MOD

invfact[1100000 -1] = pow(fact[LIM -1], MOD-2, MOD)

for i in range(LIM-1,0,1):
    inv[i-1] =invfact[i] * i %MOD

#convination
def nCk(n,k):
    return fact[n] * invfact[k] * invfact[n-k] %MOD

#permutation
def nPk(n,k):
    return fact[n] * invfact[n-k] %MOD
```

冪乗計算

```python
MOD = 10**9 +7
#x = 10**19 % MOD
x = pow(10, 19, MOD)
```

#公倍数、公約数

```python:
#最大公約数
gcd = math.gcd(a,b)

#最小公倍数
lcm = a * b // gcd
```

#Bit全探索

```python:
kajitu = ["みかん", "りんご", "ぶどう"]
kakaku = [100, 200, 300]

ans = 0
for i in range(1<<len(kajitu)):
    count = 0
    for j in range(len(3)):
        if (i >> j) & 1:
            count += kakaku[j]
    ans = max(ans, count)
print(ans)
```

#stackとqueue

```python:
stack=[1,2,3,4]
#push
stack.append(5) #stack=[1,2,3,4,5]
#pop
stack.pop() #stack=[1,2,3,4]

queue=[1,2,3,4]
#enqueue
queue.append(5) #queue=[1,2,3,4,5]
#dequeue
queue.pop(0) #queue=[2,3,4,5]

```
LaTeX WorkshopとSumatraPDFのsynctexの設定

Windows10でVScodeのlatex-workshopのexternal pdfをsmatraPDFにしてsynctexを使ったforward searchとinverse searchの設定をする．いくつか参照して試行錯誤したのでメモ．

# VScode側の設定
settings.josonに以下を追加．

```
"latex-workshop.view.pdf.viewer": "external",
"latex-workshop.view.pdf.external.viewer.command": 
        "C:\\Users\\[username]\\AppData\\Local\\SumatraPDF\\SumatraPDF.exe",
"latex-workshop.view.pdf.external.viewer.args": [
        "-reuse-instance",
        "%PDF%"
],
"latex-workshop.view.pdf.external.synctex.command": 
        "C:\\Users\\[username]\\AppData\\Local\\SumatraPDF\\SumatraPDF.exe",
"latex-workshop.view.pdf.external.synctex.args": [
    "-forward-search",
    "%TEX%",
    "%LINE%",
    "-reuse-instance",
    "-inverse-search",
    "C:\\Users\\[username]\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe \"C:\\Users\\[username]\\AppData\\Local\\Programs\\Microsoft VS Code\\resources\\app\\out\\cli.js\" -r -g \"%f:%l\"", //put same code on Smatra pdf option
    "%PDF%",
],
```

# smatraPDF側の設定
詳細設定に以下を追加

```
InverseSearchCmdLine = C:\Users\[username]\AppData\Local\Programs\Microsoft VS Code\Code.exe "C:\Users\[username]\AppData\Local\Programs\Microsoft VS Code\resources\app\out\cli.js" -r -g "%f:%l"
```
#使い方
`Ctrl+Alt+J`でVScode上のソースからsmatraPDFに飛ぶ．
PDFダブルクリックでsmatraPDFからVScode上のソースに飛ぶ．


#参考
James-Yu/LaTeX-Workshop View
https://github.com/James-Yu/LaTeX-Workshop/wiki/View,
TeX Wiki : SumatraPDF との synctex 連携
https://texwiki.texjp.org/?Visual%20Studio%20Code%2FLaTeX#g142ea7e
LaTeX WorkshopでSumatraPDFを使う
https://qiita.com/hakos/items/7178c9bdd0fbbf8f78db
Windows Terminalで「タブを新規作成」と「タブを閉じる」ショートカットをブラウザと同じにする

設定のキーバインディングに以下を入れて読み込み直すだけ。便利。

```json:settings.json
{
    "keybindings":
    [
        { "command": "closeTab", "keys": "ctrl+w" },
        { "command": "newTab", "keys": "ctrl+t" }
    ]
}

```
Karabiner-ElementsでのJIS・USのキーコード対応表

Karabiner-Elementsでは、キーコードを指定することになります。その時、接続しているキーボードがJISかUSかの認識がずれ、うまくいかない場合があります。その時に、確認すると良いキーコードをまとめました。

| JISキーボード       |      USキーボード |   指定すべきキーコード    |
|:-----------------|------------------:|:------------------:|
|^ |= |equal_sign
|¥ |なし|international3
|@ |[ |open_bracket
|[ |] |close_bracket
|: |’ |quote
|] |\ |backslash
|\ |. |international1
|; |; |semicolon
|- |- |hyphen
|, |, |comma
|. |なし|period
|/ |/ |slash
🔰Gem::LoadErrorが出て、sqlite3をバージョン指定したが改善されない。

初めまして、Macを使っており、最近ターミナルを初めて触り、Rubyをやり始めた者です。
開発環境を整える際につまづいていることについて質問をさせていただきたいです。

現状のバージョンは以下です。
![スクリーンショット 2020-07-08 14.40.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669725/0382963a-9b9e-2356-9767-f75640e6d908.png)


現在、Gemfileに'sqlite3'のみ書かれていたものを、
gem 'sqlite3', '~> 1.3.13'
と書き換えたりしましたが、ローカルホストにアクセスしようとした時に以下の表示が出てしまい、
改善されません。

![スクリーンショット 2020-07-08 15.14.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669725/7f6db731-5378-5b1d-145e-af733f2e0e96.png)


全てが初めてで、恥ずかしくなるくらい初歩的な質問になっていると思います。
ですが、どうしても自分で作っていかなければならない状況でして、回答いただけますと嬉しいです。
どうぞよろしくお願いします。
【初心者でもわかる】web制作で使われる画像3種類。[.gif]と[.jpg]と[.png]の違い。

# どうも、7noteです。今回はwebで使われる3種類の画像の使い分け方の説明。

どうも7noteです。
この記事は以下へ引っ越しました。


https://naruweb.com/coding/image_ex/
AWS CodeBuildでサポートされているはずのランタイムが利用できない場合の対処

※ 2020年7月8日現在
※ AWSにはフィードバック済み

イメージのバージョンを上げると解決する。


## 現象

GitHubとAWS CodeBuildを連携して、テストの自動実行をしていた。
プロジェクトで利用しているNode.jsのバージョンを`10`から`12`に上げる機会があり、同じくCodeBuildで扱うNode.jsのバージョンも上げることにした。

CodeBuildで扱うNode.jsは、CodeBuildでサポートされているランタイムを利用していた。
また、バージョンは`buildspec.yml`で管理していた。

12.xに対応していない可能性があるので、ドキュメントも念のため確認した。

> https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
> phases/install/runtime-versions
> The following supported runtimes can be specified.
>
Runtime name | Version | Specific version | Specific major and latest minor version | Latest version | Image/Images
--- | --- | --- | --- | --- | ---
nodejs | 12 | nodejs: 12 | nodejs: 12.x | nodejs: latest | All Amazon Linux 2 images<br>Ubuntu standard:3.0<br>Ubuntu standard:4.0 |
> （追記）AWSにフィードバックを送信したところ、"All Amazon Linux 2 images"の部分を"All supported Amazon Linux 2 images"に変更してくれました。


イメージは`amazonlinux2-x86_64-standard:1.0`を利用していた。
表の`Image/Images`の値には、`All Amazon Linux 2 images`と書かれている。
どうやらうまいこと12.xに上げることができそうだ。

そこで、`buildspec.yml`の内容を以下のように変更してみた。

```diff

version: 0.2

phases:
  install:
    runtime-versions:
-     nodejs: 10
+     nodejs: 12

  pre_build:
    commands:
      - npm install

  build:
    commands:
      - npm test -- --coverage

artifacts:
  files:
    - coverage/lcov-report/**/*

```

早速CIを実行してみたら。。エラーが発生してしまった。

```bash

YAML_FILE_ERROR: Unknown runtime version named '12' of nodejs. This build image has the following versions: 10, 8
```

`12`がサポートされていない。。ドキュメントではサポートしている記載があるのにどうして。。
`12`という記述方法がまずかったのかもしれない。`12.x`で修正し、再度実行してみたが、今度は違うエラーが発生してしまった。

```bash

YAML_FILE_ERROR: Major version of alias '12.x' is not supported in runtime 'nodejs'.
```


## 対処

もしかしたらイメージに問題があるのかもしれない。
試しに利用しているイメージを以下のように変更してみた。

`amazonlinux2-x86_64-standard:1.0` → `amazonlinux2-x86_64-standard:3.0`

CIを実行してみたところ、エラーが発生しなくなった！
どうやらAWSのドキュメントの修正漏れだったようだ。（もしくは私が何か見逃しているか）
現代フロントエンド開発シリーズ(9) - UI設計は本当に簡単ですか？UIの状態について話す

一般に、UIを設計する場合、モックアップの外観だけがあったため、Webページの設計時に注意すべきところがミスする点がよくあります。UIデザイナーとグラフィックデザイナーを区別する良い方法です。

どうしてそんなこと言いますか？

一般的なグラフィックデザインとは異なり、Webページはスクロール、マウスの移動、コンテンツの長さの変更、端末の使い、幅と高さなど、さまざまな原因でレイアウトが変わることがあります。したがって、UIを設計するのも決して簡単ではありません。

ここでは、さまざまなパターンを1つずつ紹介することはできませんが、いくつかのアイディアを説明します。

## 状態

UIを設計するときは、状態から始めることが多いです

### 空っぽい状態

テキスト、タイトル、画像などない状態ではどう表示するか。ユーザーがアカウントを作成したばかりで、情報のないページがたくさんあります。その場合はUIの表示はどうなりますか？

多くのデザイナーはこれらの状況を考慮しないことがよくあり、モックアップは理想的なUI表示で作ってしまった場合があります。開発者も注意しないと、そのままモックアップを実装され、本番環境で違った表示してしまう場合があります。この方法では、実際のアプリケーションに適用できません。

### 一般的なステータス

通常の状態で、UIはどう表示するのか

### まれな状態

まれな状態とは、通常の状況ではまれであるが、存在している状態です。たとえば、タイトルが長すぎる場合はどのように表示しますか？直接改行しますか？または、代わりに「...」を使用しますか？または、2行後に「...」を使用しますか？

もしくは実際の画像に対する画像の比率が正しくない場合はどうなりますか？たとえば、カードデザインの画像比率は16：9ですが、一部のユーザーの画像は1：1、9：16でもあります。直接カットしますか、それとも他の方法を使いますか？

## テキストレイアウトの処理

ブラウザでは、 `rem`、` em`を使って、直接書き込むことなく相対フォントサイズでデザインしています。SCSSまたはその他のツールを使って、UIをより体系的に管理できます。

また、テキストを異なるデバイスで比例的にスケーリングする必要があるかどうか、または個別に異なるフォントサイズを使用する必要があるかどうかを検討する必要があります。

## 空白

空白のシステムを管理する方法は非常に重要です。適切なギャップがあると、UIの一貫性が向上し、管理しやすくなります。たとえば、空白のシステムのセットを定義し、タイトルとタイトルの間のギャップ、カードとカードの間のギャップなどを定義することで、UIの一貫性が向上することができます。

## 読み込みステータス

データがロードされていない場合は、Placeholderを使用して実行できます。最近、いくつかの偽のUIを作成してそこに配置することがトレンドでしたが`background-positionは実際にレイアウトとペイントを発火します。あまりにも多くは良いことではないので、代わりにスピナーやgifなど使えばよいと思います

## エラーが発生した場合はどうすればよいですか？

- UIは400、404、401、402を処理できますか？ユーザーがフォームを入力している場合、ポップアップなどの表示とかしましたか？データは`localStorage`にもしくは他の方法で保存しましたか？データが直接なくなった場合、ユーザーが落ち込むことが多いので注意が必要です。

- 入力の検証は正しいですか？（対応するエラーメッセージを設計したり、考えられるエラーをカバーしたりしていますか？たとえば、パスワードの長さ、電子メールの長さ...）
- エラーメッセージは十分気づかれますか？
  - ユーザーは簡単にエラーを発見できますか？
  - ユーザーが次のステップに進むことができるように、完全な情報とフォローアップができますか？

- APIが呼び出されたときにUIがすぐに応答できますか？
  - リクエストを呼び出すとき、ロード中、保留状態とかUIに反映していますか？

### 結論

この記事ではUI設計上いくつ考えなければならないことをまとめました。ご参考になれば幸いです。
Deep Sortを使ったObject Tracking

# Object Tracking をするためにDeep Sort を使ってみた。
Yolo などのObject Detection は物体が特定の画像のどの位置(Boundary Box)に存在しているかを識別するもので、
Object Trackingは、それらの物体が、複数の連続する画像で同一のものであるかどうかを識別するものである。

まずは、Yolo などで物体検出した後に、それらの位置情報をDeep Sort に渡して、同一のobject であるか識別させ、各物体に対してそれぞれTrack IDが割り振られる。

####Deep Sort コード取得する。
こちらにあるコードを使って、YoloV4でobject Detection し、それをDeep Sort でObject Trackingする。
https://github.com/LeonLok/Deep-SORT-YOLOv4

~~~
git clone https://github.com/LeonLok/Deep-SORT-YOLOv4.git
~~~

今回は、TF2.0 を使うので、以下のフォルダに移動

~~~
cd Deep-SORT-YOLOv4/tensorflow2.0/deep-sort-yolov4
~~~

####requirement.txtを使って、必要なツールをinstallする。
自分の環境では、githubにおいてあるrequirement.txtでは動かなったので、以下のように修正した。

~~~requirement.txt
# This file may be used to create an environment using:
# $ conda create --name <env> --file <this file>
# platform: linux-64
imutils==0.5.3
keras==2.3.1
matplotlib==3.2.1
numpy==1.18.4
opencv-python==4.2.0.34
pillow==7.1.2
scikit-learn==0.23.1
scipy==1.4.1
tensorboard==2.2.1
tensorflow==2.0.0
tensorflow-estimator==2.1.0
tensorflow-gpu==2.2.0
~~~

pip installする。

~~~
pip install -r requirement.txt
~~~

####Yolov4用の重みファイルを以下からDownloadする。
https://drive.google.com/file/d/1cewMfusmPjYWbrnuJRuKhPMwRe_b9PaT/view

Downloadした、yolov4.weightsをmodel_dataフォルダにコピーし、conver.py を使って、.weightファイルから.h5フォーマットに変換

~~~
python convert.py
~~~
で、mode_data フォルダ以下にyolo4.h5は作成される。

####demo.py を実行する。

~~~
python demo.py
~~~

各物体に対して、IDが割り振られていて、特定の物体をtracking しているのが分かる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/535710/c04c37e6-4c01-0de0-044e-6e733d85b40a.png)
Linuxでいろいろ調査

# はじめに
調査の目的はいろいろですが、調査に利用した内容の備忘録です。

# コマンドを使ってみる
- top
- vmstat
- ps
- free
- tcpdump
- printenv
- size
- objdump
- readelf
- ldd
- netstat
- uptime
- lsof
- lspci
- uname
- ulimit
- perf
- strace
    - 特定システムコールのみトレース
    - 特定システムコールはトレースしない
        - [Linux日和～straceでLinuxシステムコールをトレースする～](http://linux-biyori.sakura.ne.jp/setting/st_strace.php)
    - システムコールの実行時刻、処理時間
        - [Linuxデバッグコマンド strace の基本的な使い方 - jitsu102&#39;s blog](http://jitsu102.hatenablog.com/entry/20111231/1325322559)
- bootchart
- vnstat
- iostat
- sar
- pgrep
- pmap
- debugfs
    - [削除した i-node を見つけだす](http://archive.linux.or.jp/JF/JFdocs/Ext2fs-Undeletion/sec-finding.html)

# 環境変数を使ってみる
- LD_DEBUG

# 解析してみる
## GNU GLOBAL
タグ作成

```
gtags -v
```

HTML化

```
htags -sanF
```

## OpenGrok
[Comparison with Similar Tools](https://github.com/oracle/opengrok/wiki/Comparison-with-Similar-Tools)

## gcc
- --export-dynamic
- --version-script
- --start-group
- --end-group
Mobile Safari は再起動時に POST リクエストする場合がある

Rails アプリケーションで、iPhone の Safari からのリクエストでだけ `ActionController::InvalidAuthenticityToken` 例外が発生するので調査していたところ、Mobile Safari は再起動後、開いていたタブをロードする際に、POST リクエストで得たページであっても再度リクエストを送信しているらしいことがわかった。

※ iOS 13.5.1 の iPhone 11 で検証

# 検証方法
下記の Ruby スクリプトを作成して `ruby server.rb -o 0.0.0.0` で起動

```ruby
# gem install sinatra が必要
require "sinatra"

html = <<~HTML
<!doctype html>
<form action="/" method="post">
  <input type="text" name="email">
  <button type="submit">Submit</button>
</form>
HTML

get "/" do
  html
end

post "/" do
  p params
  html
end
```

1. Mobile Safari で `http://[上記スクリプト実行したPCのアドレス]:4567` にアクセス
2. 適当に入力して submit
3. Mobile Safari を終了
4. Mobile Safari を起動 (確認などなしでページが表示される)

この手順でログを見ると、4 で 2 と同じリクエストが送られていることが確認できた。

```
x.x.x.x - - [08/Jul/2020:14:24:37 +0900] "GET / HTTP/1.1" 200 131 0.0072
{"email"=>"foo"}
x.x.x.x - - [08/Jul/2020:14:24:41 +0900] "POST / HTTP/1.1" 200 131 0.0022
{"email"=>"foo"}
x.x.x.x - - [08/Jul/2020:14:24:48 +0900] "POST / HTTP/1.1" 200 131 0.0007
```


# Rails で InvalidAuthenticityToken 例外が起こる理由と対策
Rails で...

1. Cookie をセッションストアとして使っていて、かつ有効期限が Session (デフォルト)
2. `protect_from_forgery with: :exception` を指定している

場合に、上記のように 2 度 POST リクエストが送られると、2 度めのリクエストでは Cookie がクリアされているので `session[:_csrf_token]` が nil になり、`params[:authenticity_token]` の検証が失敗し、InvalidAuthenticityToken 例外が発生してしまう。

解決策としては下記のものが考えられる。

1. POST でページを render せず、redirect してかならず GET させるようにする
2. protect_from_forgery で null_session などにする
3. Cookie の有効期限を伸ばす 

3 の場合は config/initializers 下に適当なファイルを作って下記の内容を記述すればよい。

```ruby
# key の部分はなんでもいいがデフォルトは "_#{アプリケーション名}_session"
# ここでは有効期限を 2 週間にしている
Rails.application.config.session_store :cookie_store, key: "_foo_session", expire_after: 2.weeks
```
【jQuery】　scroll スクロールすると浮き上がってくるやつ　はじめました。

##【ゴール】
![画面収録 2020-07-08 14.46.12.mov.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/620689/85004f0b-ef15-ad34-889a-bb3ccc8ac8bd.gif)
##【メリット】
■　リッチなサイト構築
■　jQuery理解度向上　


##【実装】

###手順
**＊jQueryのgem、もしくわ、ライブラリの読み込みが必要です！**
HTML記述
jQuery記述


###HTML記述
＊JSが読み込めるように「id」をつけます。

```html:hoge.html
.
.
.
.
<h2 id="text" style="display: none;">文字が遅れて見えてきます</h2>
.
.
.
.
```

###jQuery記述
＊「window」に対して、スクロールイベントを発火
＊「if」による条件分岐
　→＊「.scrollTop」が一定の数値で発火（今回は1100で設定。）
　→＊「fadeIn」でフワッと現れます。

```javascript:hoge.js
$(window).scroll(function () {
    if ($(this).scrollTop() > 1100) {
      $('.text').fadeIn(1000);
    }
 });
```

以上、jQuery記述少なくてとても便利です。。。。
##【合わせて読みたい】

■ 【jQuery】初心者でもよく理解できたやつ
https://qiita.com/tanaka-yu3/items/a03734b248c3f2ee8461

■ 【raty.js】 星付き　評価機能　実装　rails　view表示まで
https://qiita.com/tanaka-yu3/items/6aab71a46764370c00d0

■他、スクロールイベントについて
https://yuyauver98.me/scroll-show-hide-btn/
EC-cube3系でプラグインアップロード時に"Attempted to load class "ZipArchive" from the global namespace."とエラーが出た

よく忘れてしまうので備忘録として。

EC-cube3系ではプラグインの管理がちょっと面倒。
なので、しゃあなしプラグインファイルだけgitの管理から外して、手動で管理画面から管理している時があります。
その時に、圧縮ファイルをプラグイン管理画面よりアップロードするのですが、macでfinderから普通にzipファイルにしてアップすると

```
Attempted to load class "ZipArchive" from the global namespace
```
みたいなエラーが出てくる時があります。

そんな時は、ターミナルから対象プラグインを下記コマンドで `.tar.gz` に変換すればきちんとアップロードできます。

```
cd PluginFile
tar -zcvf ../PluginFile.tar.gz ./*
```

以上！！！
html周りのエラー

#メモ代わり
html周り弄ってた時のメモとして。
javascriptやらphpも込み込み(の予定)
都度都度更新してく。
###javascriptでjsonが読み込めない(404エラーを吐かれる)
<b>原因</b>
知らん！
最初は「jquery使えないせいか？」とか「jsonのパス指定が間違っているか？」とも思ったがそうでもなかったし。
ただ自前のサーバーで全く同じコードでやった時はエラー吐かれなかったからサーバの設定あたりの可能性か？
<b>オチ</b>
jsonファイルをテキスト(.txt)に変換してそれを読み込ませたところ、問題なく動作した。
読み込むコードはこんな感じ(jQuery使用)。

```js:sample.js
function sample()
{
	$.getJSON("latest_data.txt",(data) =>
	{/* 処理あれやこれや*/});
}
```
###500エラー(php)
<b>原因</b>
構文エラーの可能性が高い。
概要箇所をよく見直す事。~~と昔のボクが残したメモに書いてあった~~
<b>前やらかしたやつ</b>
・必要な部分までコメントアウトしてしまった。

```php:sample.php
<?php
for()
{内容	//こんな感じ。右の中括弧もコメントアウトされちゃってる→}
{内容}//案１：後ろにつける。
{内容/*案２：コメント部分を囲う*/}
//案２の方は全体をコメントアウトしたいときに、ここでコメントアウト切れちゃうから個人的にあまりお勧めはしない
?>
```
・末尾に;(セミコロン)を付け忘れてた
　pythonでの癖が出ちゃった。気を付けよう。
・()が閉じられていない、または余分な()がある
　構文をコピペした時にちょくちょく発生する。


###$_POSTの値が取得できない(php)
<b>原因</b>
$_POST[]の中のname指定を「'(シングルクォーテーション)」で括っていた。
「'」だと変数名がそのまま書き出されてしまい、下の例だとName名が「No\{＄n\}」となってしまうために取得できていなかったのだと思われる。
<b>オチ</b>
<b>「"(ダブルクォーテーション)」で括れ。</b>

```php:sample.php
<?php
//$_POST[]の中身が[No0] => a [No1] => bだとすると
for($n=0,$n<count($_POST[]),$n++)
{
    echo $_POST['No{$n}']; //これだとダメ
    echo $_POST["No{$n}"]; //これでOK
}

//ただしこれは送信部分が問題なくできていることが前提。
//$_POST内を確認するには以下2つの方法のどちらかで確認ができる。
VAR_DUMP($_POST);
print_r($_POST);
?>
```
nextIntとnextLineとsubstringを使うとエラーになった。


```java
import java.util.Scanner;

/*
原因はnextInt
nextIntで123と入力すると
Java側では123\nに変換され（末尾に\nが入る。）
nextIntは123だけを返す
次にnextLineを入力すると先ほどの残った\nが読み込まれ
エラーが発生する。

解決法は
変数への代入を伴わないnextLineを記述する。（以下のソースのscanner.nextLine()）
これをすることで\nが消去され次にnextLineが正常に動く

※nextIntは\nを消す機能がないためnextLineを入れる必要がある。
※バックスラッシュとnで改行を表す。

*/
public class Hello {
    public static void main(String[] args) {
    	Scanner scanner = new Scanner(System.in);

        int a = 0;
        int b = 0;
        String str = "";

        a = scanner.nextInt();
        b = scanner.nextInt();
        scanner.nextLine();
        str = scanner.nextLine();
        System.out.println(str.substring(a - 1, b));
    }
 }
```
セマンティックセグメンテーション PSPNet

# セマンティックセグメンテーションとは
セマンティックセグメンテーションとは、画像に含む複数物体に対して、物体の領域と物体名を、ピクセルレベルで付与するタスク。← 物体検出では物体を矩形領域で囲んだ

入力：画像
出力：各ピクセルが所属するクラスラベル

用途：製品の傷検出、医療画像診断における病変部分の検出、自動運転における環境把握

# PSPNet（Pyramid Scene Parsing Network）
セマンティックセグメンテーションのアルゴリズムの一つ。

# PSPNetによるセマンティックセグメンテーションの流れ
1. 画像の前処理（リサイズ、色の標準化など）
2. PSPNetのネットワークに画像を入力し、各ピクセルの各クラスの確信度（クラス数 x width x height の配列）を出力
3. PSPNetの出力が最大値のクラスを抽出
4. 3の出力の配列を元の画像の大きさに戻す

# ネットワークモデル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/397136/ef23df48-4feb-73b5-186f-0c3f33afa355.png)


# モジュール単位の説明
PSPNetは、Feature, Pyramid Pooling, Decoder, AuxLossモジュールからなる。

Feature（Encoder）：2048 x 60 x 60（ch x height x width） の特徴量を出力。特徴をつかむことが目的で、ポイントはチャネルが2048, 特徴量のサイズが60 x 60 に小さくなる部分。
Pyramid Pooling：**PSPNetの特徴的な部分**。ピクセルの物体ラベルを求めるために、周辺だけでなく、広い範囲の画像情報を利用。4種類の大きさの特徴量マップを用意。← 画像内全体を占める大きさの特徴量、画像内の半分程度、画像内の1/3程度、画像内の1/6程度の特徴量
Decoder(Upsampling)：Pyramid Poolingで小さくなった特徴量の出力を21 x 60 x 60 のサイズに拡大（クラス分類の確信度）。次に、21 x 60 x 60 に変換されたテンソルを元の入力画像のサイズ(21 x 475 x 475)に変換。

AuxLoss：上記3つだけでも、セマンティックセグメンテーションは実現できるが、AuxLossを加えることで、損失関数の計算補助を行い、Feature層途中までの結合パラメータの学習がより良くなる。具体的には、Featureモジュールから途中のテンソルを取ってきて、それを入力とし、Decoderと同様、21 x 475 x 475のテンソルに変換。

AuxLossとDecoderの両出力を画像のアノテーションデータ（正解情報）と対応させて、損失値を計算し、損失値に応じたバックプロパゲーションを行う。

そのため、AuxLossは学習時のみ利用。推論時はDecoderモジュールの出力のみでセマンティックセグメンテーション。

# 参考
* 作りながら学ぶ! Pytorchによる発展ディープラーニング
Javaのエントリーポイントについて

##エントリーポイントとは
プログラムの実行を開始する場所のことで、**一番最初に呼ばれるメソッド**になります。メソッドは、メソッドからメソッドを呼び、さらにその次のメソッドを呼ぶ、という流れで実行されていきます。その中で一番最初に呼ばれるメソッドをエントリーポイント（**開始点**）と言います。
Javaではmainメソッドがプログラム全体のエントリーポイントに設定されます（C、C++、Objective-C等の多言語でもmainメソッドがエントリーポイントとして使われます）。
なのでJavaでの **エントリーポイント = mainメソッド**と覚えておけば良さそうです。
プログラム全体のエントリーポイントとなる場所を含むルーチンをメインルーチンといい、mainメソッドを含むクラスがメインルーチンということになります。

##mainメソッドの5つの条件
Javaではmainメソッドで使う修飾子や名前、引数などのルールが厳密に決められています。

**1.アクセス修飾子はpublic
2.staticメソッド
3.メソッドの戻り値はvoid
4.メソッド名はmain（小文字）
5.メソッドの引数はStringの配列（またはStringの可変長引数[^1]）のみ**

また、Javaのメソッドは**必ず**何かのクラスに属してないといけないという決まりがあります。

以上の条件を踏まえた一般的なmainメソッドは以下のようになります。

```main.java
class Main {

    public static void main (String[] args) { 
        // 処理
    }
}

```
ちなみに、よくある引数「args」は、引数を表すargumentsを省略したものになります。

また、次のように上記の**5つの条件を外れたものは、mainメソッドとしては認識されません**。

**・引数にString型の配列を渡してない
・String型の配列以外に別の引数を渡している
・メソッド名がmainじゃない
・publicやstatic、voidを使ってない**
等


##参考サイト：
以下のサイトがとても勉強になりました。mainメソッドについてさらに詳しい解説もあります。
[Javaの実行に欠かせないmainメソッド、その仕組みからしっかり解説](https://engineer-club.jp/java-main#:~:text=Java%E3%81%AEmain%E3%83%A1%E3%82%BD%E3%83%83%E3%83%89%E3%81%AF,%E3%82%AC%E3%83%83%E3%83%81%E3%83%AA%E6%B1%BA%E3%82%81%E3%82%89%E3%82%8C%E3%81%A6%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)

[^1]: ... 個数が不定（可変）である引数のこと。
typescriptでJavaScriptライブラリを使う方法 ②

本記事は前回の記事の続きになります。

前回の記事は[こちら](https://qiita.com/nakashun1129/items/ba6b4a25e65aa1353d54)です。

さて、今回はデクラレーションファイルのないサードパッケージ製パッケージをtypescriptで使用する方法について紹介します。


<h2>誰かが既に作成していないかを確認する。

今回はlodashを使用します。

下記のコマンドでインストールします。

`npm install lodash`

そして、tsファイル上でimportします。

```ruby:library.ts
import _ from 'lodash';
```
すると、エラーが出るはずです。

node_modulesのディレクトリの中のlodashの中身を見てみましょう。

デクラレーションファイルがありませんね。

こういう時に一番最初に試して欲しいのが、

**既存の型定義ファイルがないかを確かめることです。**

確かめる方法は、**「@types/lodash」**でGoogle検索してみましょう。
<img width="646" alt="スクリーンショット 2020-07-08 13.52.49.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472442/8bde1351-fb39-f4e9-bf20-c36647ca34c7.png">
出てきましたね。

実際に開き、githubのリンクがあるのでクリックすると、

DefinitelyTypedというリポジトリがあります。
<img width="1440" alt="スクリーンショット 2020-07-08 13.57.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472442/f9725650-4efd-1d0c-a07f-60ccbaaf3ef8.png">

このリポジトリは、typescriptの公式のリポジトリで、開発者以外でもコミットできるようになっています。（プルリクエストはtypescriptの開発チームが毎回確認しているので安全性は高いです）

このDefinitelyTypedというリポジトリの中のtypesディレクトリの中にデクラレーションファイルが入っています。

なので誰かが既に型定義ファイルを作成していてば使用できるということになります。

それでは、使い方について説明していきます。

下記のコマンドでインストールできます。

`npm install --save-dev @types/lodash`

問題なくインストールできればエラーが消えるはずです。

試しに使ってみましょう。

```ruby:library.ts
import _ from 'lodash';
_.shuffle([1,2,3,4])
```
エラーが出ていないと思います。

以上がデクラレーションファイルのないサードパッケージ製パッケージをtypescriptで使用する方法です。

この方法を使えば、ほとんどのサードパッケージ製パッケージを使うことができますので覚えておきましょう。

<h2>余談

先ほどのコマンドでインストールしたデクラレーションファイルはどこに保管されるのでしょうか。

node_modulesディレクトリのnodeディレクトリに保管されます。
<img width="439" alt="スクリーンショット 2020-07-08 14.11.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/472442/b2f597e6-487f-eed8-8c0f-523a9ec9a12c.png">
Amazon EC2 LinuxでLaravelのphp artisan db:seedが上手くいかない時


##【エラーメッセージ】
```
[ec2-user@ip-172-31-11-201 sample]$ php artisan db:seed

In DatabaseSeeder.php line 14:

  Parse error: syntax error, unexpected end of file
```

##【開発環境】

Amazon EC2 Linux
Windows 10 HOME
Apache/2.4.43
Laravel Framework 5.4.36
vsftpd: Ver 3.0.2

Tera Term 4.1.105
FFFTP Ver 4.7

##【対応】
ローカルで同じファイルで実行出来たのでAWSに上げる過程で何をやったか？と考えてみると、、

FTPか?

まさかと思って文字コードの設定を見てみると

SJIS　になっていた。。
(FFFTPでは初期設定してもローカル側の文字コードが勝手に変わる現象を思い出した。)

これをUTF8に直して再び　「php artisan db:seed」を実行すると

```
[ec2-user@ip-172-31-11-201 sample]$ php artisan db:seed
Seeding: BooksTableSeeder
```

と成功しテーブルへの設定も問題なし。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/669259/96e1bd6c-ff4e-53be-d2e5-2a290fb72ce6.jpeg)


##【参考】

###<a href="https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d" target="_blank">Laravel入門 - 使い方チュートリアル</a>

<!--
### [Laravel入門 - 使い方チュートリアル](https://qiita.com/sano1202/items/6021856b70e4f8d3dc3d)

-->
【AmazonConnect】問い合わせの検索

#はじめに
弊社社内電話をAmazonConnectへ移行しました。
学んだことを記載していきます。

#問い合わせの検索-概要
インスタンス内の問い合わせについて、2 年前までの問い合わせを一度に 14 日間検索できます。
特定のクエリの検索結果は、返される最初の 10,000 件に制限されます。


会話が記録されたかどうかを確認するには、[Manager monitor (Manager モニター] のアクセス許可を持つプロファイルに割り当てる必要があります。

その他、詳細はAWS公式ドキュメントをご参照ください。

- AWS > ドキュメント > Amazon Connect > 管理者ガイド >
[問い合わせの検索](https://docs.aws.amazon.com/ja_jp/connect/latest/adminguide/contact-search.html)

以下、検索方法を記載していきます。

#問い合わせの検索-検索方法
①　[CallCenterManager] セキュリティプロファイルが割り当てられたユーザーアカウント、または[問い合わせの検索] のアクセス許可が有効になっているユーザーアカウントを使用して、AmazonConnect にログインします。※Admin権限にはデフォルトで付与されてます。

②　Amazon Connect で、[メトリクスおよび品質]、[問い合わせの検索] の順に選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/7f0ecdb8-7d25-b5ce-cd4f-90e338369a30.png)


③    ページのフィルターを使用して、検索を絞り込みます。

**以下、各フィルターの説明をします。**

■開始日、終了日
　開始日、終了日の範囲のデータを検索します。
　一度に最大 14 日間検索できます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/bfe876df-3571-5877-6214-4b897f5b032b.png)

■タイムゾーン
　選択した都市の時間帯に合わせて検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/1d746f95-db52-d124-579e-ff50b0d5a9a6.png)

■初期化メソッド
　以下の一覧から特定の操作を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/247a07a6-6e7f-5b19-fa14-abb5a275eb7b.png)

■電話番号
　指定の電話番号で検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/8f0d393e-ec9d-f115-2c35-b77bfa0b8b5c.png)

■キュー
　顧客がオペレータと通話する際の待ち行列を検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/c63a180a-1504-2519-9e74-5ab6c8b658dc.png)

■エージェントログイン
　特定のエージェントを指定し検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/4971e59c-ab56-00f3-54f0-41a16b61e341.png)

■最小・最大やり取り時間(秒)
　最小・最大のやり取り時間を指定し検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/da1e411f-9b9c-bf64-544e-b75ae4ac142f.png)

■チャネル
　顧客とやり取りした通信経路(音声、チャット)を選択して検索できます。
　※音声の場合、顧客の電話番号を指定して検索できます。
　音声、チャットが選択されていない場合、検索はレポートの時間範囲内のすべての連絡先を返します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/7d25977d-d968-5dbb-5b5f-142276f560cd.png)

④   検索結果に追加の列を表示するには、[追加フィールド] を展開して、表示する他のデータを選択します。[適用] を選択して列を表示します。
※検索結果に追加して表示したい項目を選択できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591271/32421778-c88e-a511-8a0a-f0e18591c717.png)

#まとめ
問い合わせの検索を活用することで、「いつ、だれが、だれと、どんな手段で、どのくらいやり取りしたのか」等が分かります！
特定エージェントへ負荷が偏っていないか・・・、特定のお客様からの架電が多い！等を分析し、意思決定に活かせると思います。
UIPickerView 文字のサイズを合わせる

## UIPickerViewの選択肢が長くて入らない場合
UIPickerView上のラベルの文字サイズを調整してピッカー内に入るようにする。

```swift
func pickerView(_ pickerView: UIPickerView, viewForRow row: Int, 
        forComponent component: Int, reusing view: UIView?) -> UIView 
{
    let label = (view as? UILabel) ?? UILabel()
    label.text = self.addresses[row]
    label.textAlignment = .center
    label.adjustsFontSizeToFitWidth = true
    return label
}
```

view が取れない場合もあるので ` ?? UILabel()` を忘れないように
How to install Parallels Tools on Vagrant

#### [Vagrant](https://www.vagrantup.com/) を [Parallels Desktop](https://www.parallels.com) で動かす際、Parallels Tools ([VirtualBox](https://www.virtualbox.org)でいうところの Guest Addtion みたいなもの) をインストールする方法

`Vagrantfile` に下記のように追加します。

```.rb
Vagrant.configure("2") do |config|
  # 略

  config.vm.provider :parallels do |p|
    p.update_guest_tools = true
  end
end
```

#### 参考にしたページ
[Guest Tools never detected as Installed · Issue #127 · Parallels/vagrant-parallels](https://github.com/Parallels/vagrant-parallels/issues/127)
PuppeteerでFirefoxを利用するための知見

## 前置き

Puppeteerでは現在(2020/07/08)、Chrome(Chromium)に加えFirefoxでも動作させることができます。
簡単ですが上手く動作させることができましたので、それまでの知見をまとめます。


## 検証環境

Windows 10 Pro 1903
puppeteer @4.0.0
Firefox Nightly 80.0a1


## 準備

1. Puppeteerのインストール(詳細省略)
2. Firefox Nightlyのインストール [プレリリース版ダウンロードサイト](https://www.mozilla.org/ja/firefox/channel/desktop/)

Firefoxは通常版だとダメで、ブラウザを起動させた後に処理が止まりタイムアウトしてしまいます。
Puppeteerは3.0以上で対応しているようです。[^infoq]


## ソースコード(抜粋)

```
const browser = await puppeteer.launch(
    {
        product: 'firefox',    // 1. 'chrome' or 'firefox'
        executablePath: 'C:\\Program Files\\Firefox Nightly\\firefox.exe',    // 2. Firefox(Nightly)の実行パス 
        userDataDir: 'C:\\work\\Profile_FirefoxNightly',    // 3. ユーザープロファイルの保存ディレクトリパス
        args: ['-wait-for-browser']    // 4. Firefox(Nightly)の起動を待つ
    }
);
```

1. 現在は'chrome'か'firefox'のみ指定できます。chromeはデフォルトなのでFirefoxで動作させたいときのみ必須です。launchメソッドの引数としてではなく、環境変数でも'PUPPETEER_PRODUCT'の変数名でも登録して設定することが可能のようです。
2. 実行パスは絶対パスでも相対パスでも記述可能らしいです。自分でインストールしたchromeを使用する場合にもこの項目を使用します。
3. ユーザープロファイルの保存ディレクトリパスを指定しないと、ブラウザの起動はできますが終了時(`await browser.close();`)にエラーが発生します。指定するディレクトリは空で良いですが、初回起動時に「既定のブラウザに設定するか」などのダイアログが出るので、本利用前に一度起動してもろもろ設定しておいた方が良いです。
4. `-wait-for-browser`を指定しないと、ブラウザの起動途中で処理が進んでしまい、エラーになります。`-wait-for-browser`はFirefox用のオプションのようです。

詳細はPuppeteer公式ドキュメントの`puppeteer.launch([options])`の項を参照ください。
[Puppeteer API v5.0.0](https://github.com/puppeteer/puppeteer/blob/v5.0.0/docs/api.md#puppeteerproduct)


## メモ

一度の処理の中で`await puppeteer.launch`を複数回行う場合、`product: `オプションは一度設定すると後のすべてで有効になるようです。
それに対し`executablePath: ``userDataDir: ``args: `オプションは毎回設定することが必要です。
`product: `オプションは環境変数に設定したのと同じような扱いということなのかも？
一度の処理の中でChromeとFirefoxの両方を使用したい場合は都度`product: `オプションを指定すれば大丈夫なようです。


## その他

Puppeteerが公式でFirefoxをサポートしたことにより、puppeteer-firefoxはdeprecatedになったようです。[^puppeteer-firefox]

PlaywrightというChromiumとFirefoxに加えWebKitもサポートしている同様のツールがあるそうです。[^playwright]
参考：[Playwrightも知らないで開発してる君たちへ](https://qiita.com/cc822jp/items/6f786a9ed104af1a382f)


[^infoq]: [Browser-Automation Library Puppeteer Now Supports Firefox](https://www.infoq.com/news/2020/04/puppeteer-3-firefox-support/)
[^puppeteer-firefox]: [puppeteer-firefox](https://www.npmjs.com/package/puppeteer-firefox)
[^playwright]: [Playwright](https://github.com/microsoft/playwright) ← Microsoft!?!?
【C#】DBの取得と値変更

######単一の項目を取得する場合は下記を記述
```C#
   var 型1 ＝ (クラス);
   var 型2 ＝ aList.Single();
   型2.項目名 = (変更値);
```
<br>(例)

```C# 
   var aList = TestClass;
   var a = aList.Single();
   a.SList += 1;
```
GoogleSpreadsheetのquery

これはプログラムなのか、と言われると微妙なんだけど、GAS繋がり。

#1.SpreadSheetのQuery関数について

## 集計
よくスプレットシートで、データを作成すると思います。

|番号 |名前 |数量 |開始日 |終了日 |
|---|---|--:|---|---|
| 1 |神奈川 | 1 |07/01|07/05|
| 2 |神奈川 | 2 |07/06|07/10|
| 3 |千葉 | 4 |07/01|07/05|
| 4 |千葉 | 3 |07/06|07/12|
| 5 |埼玉 | 9 |07/01|07/21|

ここで、各県ごとの最初の開始日と最後の終了日が欲しい場合、以下のQuery関数で一発で出てくる
※B3が左上のセルとなっている

>=query(B3:F7,"select C ,Sum(D),Min(E),Max(F) group by C")

これを入力したセルの上に

|名前 |数量 |開始日 |終了日 |
|---|--:|---|---|
|千葉 | 7 |07/01|07/12|
|埼玉 | 9 |07/01|07/21|
|神奈川 | 3 |07/01|07/10|

という結果が表示されます
 
## 検索

Filterでもできますが、こんな感じ

>=query(B3:F7,"select C,D,E,F where C ='神奈川'")

同じくこれを入力したセルの上に

|番号 |名前 |数量 |開始日 |終了日 |
|---|---|--:|---|---|
| 1 |神奈川 | 1 |07/01|07/05|
| 2 |神奈川 | 2 |07/06|07/10|

となります

## 癖

列名は大文字アルファベット、又はCol1、Col２というフォーマット。（Cは大文字必須）
SQL文法どこまで実装されてるか分かりませんが、結構使い出がありそう


## こんな利用の仕方

第一引数の範囲を他のシートにすることもできます

>=query(importrange(URL,RANGE),"select ...")

## 久しぶりに

Qita書こうと思ったら又マークダウン忘れてた
TypeScript4.0でNull合体代入演算子（??=）が導入されました

## はじめに

[TypeScript 4.0 Beta](https://github.com/microsoft/TypeScript/releases/tag/v4.0-beta)が2020/07/07にリリースされました。

この記事は[リリースノート](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/)の中で個人的に気になった機能、Null合体代入演算子について共有するためのものです。

### おことわり

~~この記事はBeta版に関するものです。正式リリース時に内容が変更になる可能性があります。~~

TypeScript 4.0が2020/08/20に[正式リリースされました](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/)。Null合体代入演算子も[予定通り導入されました](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0/#short-circuiting-assignment-operators)。

## Nullish Coalescing Assignment Operator

TypeScript4.0では、Null合体代入演算子（Nullish Coalescing Assignment Operator）が導入される予定です。

[Announcing TypeScript 4.0 Beta](https://devblogs.microsoft.com/typescript/announcing-typescript-4-0-beta/#short-circuiting-assignment-operators)

この演算子を議論しているIssueはこちらです。

[issue ＃37255 : Nullish Coalescing and Logical Compound Assignments](https://github.com/microsoft/TypeScript/issues/37255)

ECMAScriptのproposalはstage3です。

[proposal-logical-assignment](https://github.com/tc39/proposal-logical-assignment)

### 機能

この演算子は、その名の通りTypeScript3.7で導入されたの[Null合体演算子](https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-7.html#nullish-coalescing)`??`と代入を組み合わせた演算子です。

たとえば、以下の2行はまったく同じ意味になります。

```js
obj.x ??= 42;
obj.x = obj.x ?? 42;
```

+ `obj.x`が`null`か`undefined`の場合のみ、右辺の値が代入されます。
+ `obj.x`が`0`や`""`や`false`などの[Falsy](https://developer.mozilla.org/ja/docs/Glossary/Falsy)な値の場合は代入されません。

### どんなときに使うのか

たとえば

-   関数の引数にオブジェクトを使う
-   オブジェクトは複数の省略可能なプロパティを持つ
-   省略した場合、デフォルト値を代入する

という場合にコードが簡潔になります。

```js
function f(option?:
  {
    val1?: string,
    val2?: string
  }
): void {
  option ??= {};
  option.val1 ??= "default1";
  option.val2 ??= "default2";
}
```

## 参考記事

[PHP: Null合体代入演算子(??=)の使い所を考えてみた](https://qiita.com/suin/items/e70de890af6f570a2ac8)
csv-parser モジュールでCSV文字列を処理したい場合の方法



## csv-parser で CSV文字列をパースする。

https://www.npmjs.com/package/csv-parser

上のモジュールで単純なCSV文字列をパースしたい場合はリーダブルストリームを
一旦生成することで csv-parserのインターフェイスを合わせる事ができる。
（もっと簡単な方法がありそう


``` typescript
import csvParser from "csv-parser"
import { Readable } from "stream"

//CSVが格納された文字列
const csvString = `col1,col2,col3
row1,row2,row3
row1,row2,row3`

// Readable Stream を作成
const readable = new Readable({
    read:(size) => {
        //この処理の記述の必要性が実は良く分からない
        return true
        }
})

readable.on("data",(chunk) => {
   //parse されたデータ
   console.log(chunk)
})
.on("err",(err) => {
   //error 時の処理
})
.on("end",() => {
   //終了時の処理
})
.write(csvString,(err) => { //CSV文字列をストリームに書き込む
    //close イベントを emit する

    readable.emit("end")
})


```

Promiseが必要であれば end コールバックでResolveすれば多分OK。
PWA対応のWEBアプリに興味をもったので調査

# PWAの魅力


### ホームスクリーンへの追加を促すことが出来る

使用するブラウザAPI：WebManifest

- 「ホームに追加」ボタンを表示でき、ホームに追加されたページはインストールされたアプリのように扱える
- ホーム画面のアイコンが設定できる

### キャッシュでオフライン対応、ページの高速化が出来る

使用するブラウザAPI：Service Worker Caching

- オフラインでのリクエストをためておき、オンラインになったタイミングで処理を進めることが出来る

### プッシュ通知を送ることが出来る

使用するブラウザAPI：Push Notifications


### この他にも様々なAPIがPWAで使えるようになっている
参考にしたページ：[これからPWAでつかえるようになるAPI](https://qiita.com/moksahero/items/e753d4b3285b8a975c0d)


# PWAに必要な環境構築の候補

-  Web Starter Kit
    -  複数の記事を見た感じ、Web Starter Kitの導入で完結してて、Web Starter Kitを利用したPWA実装記事が少ない
     
- Vue.js開発環境 ＋ Workbox(ServiceWorker生成ツール)
    - PWAの雛形 （vue-pwa-boilerplate）とかも使うと便利かも
    
- React.js開発環境
    - create-react-appを使ってプロジェクトを作成するとデフォルトで用意されている。
EFSにセットアップしたPythonライブラリをLambdaにimportする方法


# はじめに

**Lambda**に**EFS**をマウントできるようになりました。これによりEFSにセットアップしたPythonのライブラリをLambdaにimportできるようになりました。  
  
これまでは、LambdaにPython標準以外のライブラリをimportしたい場合は、Lambda layer に固めてアップロードする方法しかありませんでした。しかし、この方法には `圧縮して50MB以下、解凍後250MB以下というサイズの制限`があります。このため、サイズの大きいライブラリを複数使うといったことができませんでした。そのため、少し規模が大きいシステムだと、一部処理をdockerに外出しするなどの対応が必要となり、Lambdaだけでは完結しませんでした。

しかし、LambdaにEFSをマウントできるようになったため、この問題が解消します。`EFSにインストールしたライブラリをLambdaにimportできるようになりました。`

# how to

## 概要

1. EFS作成
2. EFSアクセスポイントを作成
3. EFSを作業用にEC2にマウント
4. EFSにPythonとライブラリをインストール
5. Lambdaにimport

## 手順

1. EFS作成
    - 作成手順  
    省略
    - 注意  
    Lambdaと同じVPCを指定  
    セキュリティグループ port:2049 許可にLambdaのセキュリティグループを指定
2. EFSアクセスポイント(クライアントアクセス)を作成  
所有者ユーザーID: 1001  
所有者グループID: 1001  
アクセス許可: 777  
パス(ディレクトリ)はここでは `/lambda` を設定  
3. EFSを作業用EC2にマウント  

    ```shell
    sudo yum install -y amazon-efs-utils
    cd /mnt
    sudo mkdir efs
    sudo mount -t efs fs-xxxxx:/ efs
    ```
4. EFSにPythonとライブラリをインストール
ここでは Python3.8.1 と pandas をインストール  

    ```shell
    sudo yum -y install gcc openssl-devel bzip2-devel libffi-devel
    wget https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz
    tar xzf Python-3.8.1.tgz

    cd Python-3.8.1
    sudo ./configure --enable-optimizations
    sudo make altinstall

    # check
    python3.8 --version
    pip3.8 --version

    cd /mnt/efs
    pip3.8 install --upgrade --target lambda/ pandas
    ```
5. Lambda関数を設定
VPCに所属させる必要がある
Lambdaの実行roleにポリシー `AmazonElasticFileSystemClientReadWriteAcces` を追加
EFSを追加
6. Lambdaでimport
こんなかんじでimportできる。

    ```python
    import sys
    sys.path.append("/mnt/efs")
    import pandas as pd
    ```
Python で浮動小数点数 float のメモリ上のバイト列を確認してみる

※注(py3はもっとシンプルな方法があった)

```python
>>> import ctypes
>>> f = ctypes.c_float(0.5)
>>> f
c_float(0.5)
>>> memoryview(f).tobytes()
b'\x00\x00\x00?'

>>> memoryview(f).cast('B', shape=(4,))[3] = 0x3e
>>> f
c_float(0.125)
>>> memoryview(f).cast('B', shape=(4,))[3] = 0x40
>>> f
c_float(2.0)
>>> memoryview(f).cast('B', shape=(4,))[:] = bytes([0x3a, 0xcd, 0x13, 0xbf])
>>> f
c_float(-0.5773502588272095)
```

ctyes の使い方をいつも忘れるのでメモ。
a = 0.5 のときの a のメモリ上のバイト列を観たい。

```python
>>> import ctypes
>>> a = ctypes.c_float(0.5)
>>> a
c_float(0.5)
>>> a.value
0.5
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_float))
<__main__.LP_c_float object at 0x000001FF2A2F59C8>
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_char))
<ctypes.LP_c_char object at 0x000001FF2A2F5B48>
>>> ctypes.cast(ctypes.byref(a), ctypes.POINTER(ctypes.c_char))[0:4]
b'\x00\x00\x00?'
```

[0:4] で範囲指定しておかないと怒られる。([:]だとエラー)
出力が判り易い様に修正。

```
>>> b = lambda f: [f'{b:02x}' for b in ctypes.cast(ctypes.byref(ctypes.c_float(f)), ctypes.POINTER(ctypes.c_char))[0:4]]
>>> b(0.5)
['00', '00', '00', '3f']
```

ついでにその他の数値は、

```python
>>> b(0.25)
['00', '00', '80', '3e']
>>> b(0.866)
['2d', 'b2', '5d', '3f']
>>> b(0.433)
['2d', 'b2', 'dd', '3e']
>>> b(0.216)
['1b', '2f', '5d', '3e']
>>> b(0.0)
['00', '00', '00', '00']
>>> b(1.0)
['00', '00', '80', '3f']
```

逆も確認(バイト列から float)。

```python
>>> f = lambda b: ctypes.cast(ctypes.create_string_buffer(b), ctypes.POINTER(ctypes.c_float))[0]
>>> f(b'\x2d\xb2\x5d\x3f')
0.8659999966621399
>>> f(b'\x2d\xb2\xdd\x3e')
0.43299999833106995
>>> f(b'\x2d\xb2\x5d\x3e')
0.21649999916553497
>>> f(b'\x3a\xcd\x13\xbf')
-0.5773502588272095
```
【R】ROC曲線を複数書く

備忘録的なやつです。

前回の続き。
[【R】ROC曲線を書く](https://qiita.com/fogdiffusion/items/2b4c380fb19f6f656e32)

Rを使ってROC曲線を比較します。

使う関数は**roc()**と**roc.test()**です。

#ROC曲線を書く

```R
#Rをきれいにする
rm(list = ls())

#ライブラリの読み込み
library(pROC)

#データの読み込み
df <- aSAH

#データの確認
summary(df)
```

⬇実行結果

```R
> #Rをきれいにする
> rm(list = ls())
> 
> #ライブラリの読み込み
> library(pROC)
Type 'citation("pROC")' for a citation.

 次のパッケージを付け加えます: ‘pROC’ 

 以下のオブジェクトは ‘package:stats’ からマスクされています: 

     cov, smooth, var 

> 
> #データの読み込み
> df <- aSAH
> 
> #データの確認
> summary(df)
 gos6   outcome      gender        age       wfns       s100b            ndka       
 1:28   Good:72   Male  :42   Min.   :18.0   1:39   Min.   :0.030   Min.   :  3.01  
 2: 0   Poor:41   Female:71   1st Qu.:42.0   2:32   1st Qu.:0.090   1st Qu.:  9.01  
 3:13                         Median :51.0   3: 4   Median :0.140   Median : 12.22  
 4: 6                         Mean   :51.1   4:16   Mean   :0.247   Mean   : 19.66  
 5:66                         3rd Qu.:61.0   5:22   3rd Qu.:0.330   3rd Qu.: 17.30  
                              Max.   :81.0          Max.   :2.070   Max.   :419.19 
```

ここまでは前回と同じ。

今回は、**s100b**、**ndka**がどの程度**outcome**を予測するのかをROC曲線で評価し、比較します。

まず、**s100b**について。

```R
ROC1 <- roc(outcome ~ s100b, data = df, ci = TRUE)
ROC1
```

⬇実行結果

```R
> ROC1 <- roc(outcome ~ s100b, data = df, ci = TRUE)
Setting levels: control = Good, case = Poor
Setting direction: controls < cases
> ROC1

Call:
roc.formula(formula = outcome ~ s100b, data = df, ci = TRUE)

Data: s100b in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.7314
95% CI: 0.6301-0.8326 (DeLong)
```

ROC曲線を描きます。

```R
plot(ROC1, 
     lty = 1,　#直線
     legacy.axes = TRUE
     )
```

⬇描画結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/ff605a81-57ba-e395-734d-3dbeaebd11d0.png)

続いて、**ndka**について。

```R
ROC2 <- roc(outcome ~ ndka, data = df, ci = TRUE)
ROC2
```

⬇実行結果

```R
> ROC2 <- roc(outcome ~ ndka, data = df, ci = TRUE)
Setting levels: control = Good, case = Poor
Setting direction: controls < cases
> ROC2

Call:
roc.formula(formula = outcome ~ ndka, data = df, ci = TRUE)

Data: ndka in 72 controls (outcome Good) < 41 cases (outcome Poor).
Area under the curve: 0.612
95% CI: 0.5012-0.7227 (DeLong)
```

ROC曲線を描きます。

``add = TRUE``でさっき作成した**s100b**のグラフに**ndka**の曲線を加えます。

```R
plot(ROC2, 
     lty = 2,　#点線
     add = TRUE　# add = TRUEでさっきのグラフに加える
     )
```

⬇実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/471633/8af0c734-2d52-bfcf-c650-51d88c682ca6.png)


#ROC曲線の比較
**roc.test()**関数で2つのAUCを比較します。

``roc.test(ROC1, ROC2)``

``ROC1, 2``：**roc()**で作成したオブジェクト

```R
roc.test(ROC1, ROC2)
```

⬇実行結果

```R
> roc.test(ROC1, ROC2)

	DeLong's test for two correlated ROC curves

data:  ROC1 and ROC2
Z = 1.3908, p-value = 0.1643
alternative hypothesis: true difference in AUC is not equal to 0
sample estimates:
AUC of roc1 AUC of roc2 
  0.7313686   0.6119580
```

この結果から、2つのROCを比較した検定結果はp = 0.1643でした。
**s100b**と**ndka**の予測能に有意差は見られませんでした。
LaravelでLINE BOT（オウム返し）を実装する。

Laravel 5.5

LINE BOTのオウム返しをlaravelで実装してみる。

line-bot-sdk-phpをインストールする。

```
composer require linecorp/line-bot-sdk
```

route/api.phpにwebhookURLを設定する。

**注意：route/web.phpに設定してしまう事があるので間違えないようにする。**

```route/api.php
Route::group(['namespace' => 'Api'], function() {
    // LineからのWebhookを受信
    Route::post('/line/webhook', 'LineController@webhook')->name('line.webhook');
});
```

LINE Developersで設定したチャンネルから
チャンネルアクセストークン、チャンネルシークレットを確認し
.envに設定する


```.env
LINE_ACCESS_TOKEN=*********チャネルアクセストークン**********
LINE_CHANNEL_SECRET=*********チャネルシークレット**********
```



```Api/LineController.php
<?php

namespace App\Http\Controllers\Api;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use LINE\LINEBot;
use LINE\LINEBot\Constant\HTTPHeader;
use LINE\LINEBot\SignatureValidator;
use LINE\LINEBot\HTTPClient\CurlHTTPClient;
use LINE\LINEBot\MessageBuilder\TextMessageBuilder;
use Exception;

class LineController extends Controller
{
    public function webhook (Request $request)
    {
        $lineAccessToken = env('LINE_ACCESS_TOKEN', "");
        $lineChannelSecret = env('LINE_CHANNEL_SECRET', "");

        // 署名のチェック
        $signature = $request->headers->get(HTTPHeader::LINE_SIGNATURE);

        if (!SignatureValidator::validateSignature($request->getContent(), $lineChannelSecret, $signature)) {
            // TODO 不正アクセス
            return;
        }

        $httpClient = new CurlHTTPClient ($lineAccessToken);
        $lineBot = new LINEBot($httpClient, ['channelSecret' => $lineChannelSecret]);

        try {
            // イベント取得
            $events = $lineBot->parseEventRequest($request->getContent(), $signature);

            foreach ($events as $event) {
                // ログファイルの設定
                // $file = __DIR__ . "/log.txt"
                // file_put_contents($file, print_r($event, true) . PHP_EOL, FILE_APPEND);
                // 入力した文字取得
                $message = $event->getText();
                $replyToken = $event->getReplyToken();
                $textMessage = new TextMessageBuilder($message);
                $lineBot->replyMessage($replyToken, $textMessage);
            }
        } catch (Exception $e) {
            // TODO 例外
            return;
        }
        return;
    }
}
```



※変数の中身の見方（logファイルの設定）
LINEBotは、変数をddなどで確認できないので
ログファイルに変数などを書き込み正しくデータが取れているか確認する。
これ以外の方法もあるので各自調べてください。

log.txtの権限も編集しておいてください。
`chmod -R 777 log.txt`

```
file_put_contents(__DIR__ . "/log.txt", print_r($event, true) . PHP_EOL, FILE_APPEND);
```
VSCodeでmdをスライドにする

## VSCodeのMarp拡張機能でスライドを作成する
MarkDownを記述する時は、何だかんだで、`VSCode`が一番気に入っています。PDFを作成するのも非常に簡単ですし。
**先週LGTMが多かった投稿ベスト20**で、惹かれるタイトルを発見！
- [【VS Code + Marp】Markdownから爆速・自由自在なデザインで、プレゼンスライドを作る](https://qiita.com/tomo_makes/items/aafae4021986553ae1d8?utm_source=Qiita%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B9&utm_campaign=18c953da4b-Qiita_newsletter_418_07_08_2020&utm_medium=email&utm_term=0_e44feaa081-18c953da4b-33173157)
良いじゃないですか！`ushiday`みたいな、20年選手で、Web1.0を知っている世代からすると、「凄い時代になったものだ」と関心します。
Marp拡張機能の導入や詳細は、投稿をご参考に…。

## 実際の使用例
先程の投稿を参考に、早速試しました。
実際の使用感としては、mdがそのままスライドになるので、超便利ですね。
[github ushiday/vscode-md-marp](https://github.com/ushiday/vscode-md-marp.git)
すると以下の様な`md`が、綺麗なスライドになっちゃいます。良いですね！

```md
---
marp: true
theme: uncover
---
<!--
_color: white
footer: 'ushiday@Chubu System Co.,Ltd.'
paginate: true
-->

![bg brightness:0.6](./power/servers09.jpg)

# ushiday marp
Marp = mdよりスライドを作成するプラグイン
## (50) ushiday Marpを試す

`bg brightness`を使うと背景の透過を変更出来る

作成日 : 2020.07.08  **(ushiday)**

---
![bg left:50%](./power/E980-r.png)

## 左に画像を挿入
`bg left`で左に画像を差し込む

- 表示場所、比率を指定する

---

<!--
_backgroundColor: white
-->
![bg right:60% height:50% contrast:1.0 brightness:1.0](./power/ibmi-logo.png)
![bg right:60% height:50% contrast:1.2 brightness:1.0](./power/csc-logo.jpg)

# CSC は
#### IBM i と

共に進む…
```

### PDF化
![2020-07-08_123504.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/100029/f36d780c-841c-a67b-6da0-94a96745861c.png)
ゼロサプレスなしってゼロがあるんだっけないんだっけ

## ゼロサプレスなし？

先輩「日付はいつもの年月日時分秒みたいな感じね。
あ、ゼロサプレスなしで」
ぼく「はい！！！！！！！！！！（ゼロサプレスなしってゼロがあるんだっけ？　ないんだっけ？）」

コインを投げて裏か表かで決めたら、５０％の正解率になる。
半分の確率で怒られが発生することだろう。

### サプレス＝抑圧
サプレスは、suppress(抑制する)だから、余計なゼロはなしだ。
つまり2020年7月3日なら2020/7/3という感じだ。
ゼロサプレスなしは、suppress(抑制する)＋なしだから、抑圧しない＝ゼロで埋めておいての意味である。
つまり2020年7月3日なら2020/07/03という感じだ。

まあ、大体の場合、日付は桁数がそろうので、ゼロで埋めることが多いと思う。


何で間違っちゃうんだろう。
サプレスのサプがsupply（供給）と似ているのかもしれない。
plus（足す）って響きに似ているのもよくない。

サプレス（抑制する）だ。
ついでに、語源はsub（下に）、 premō 「押す（press）」、 『下に押す、押しつけてやめさせる』のようだ。
ゼロサプレスはゼロをぎゅうぎゅうに押しつぶしてなかったことにするのだ。
ゼロサプレスなしならゼロはある。またわからなくなった？

参考：[サプレス IT用語辞典　e-Words](http://e-words.jp/w/%E3%82%B5%E3%83%97%E3%83%AC%E3%82%B9.html)
HTTP通信 エラー番号 種類

## HTTP 通信をする際のerror番号の内容一覧

**HTTPレスポンスのステータス番号の一覧**
200番台は、正常処理(成功)を意味します。
300番台は、リダイレクト関連です。
400番台は、クライアン側のエラーです。
500番台は、サーバー側のエラーです。

|番号|エラー内容
|------|---------|
|200|OKリクエストが成功しレスポンスが返されます。正常処理を表します。|
|301|Moved Parmanently指定したリソースは移動したので、新しい場所から取得して下さい。サイトの引越しをしたときは、この値を設定します。|
|302|Moved Temporarily指定したリソースは一時的に移動したので、新しい場所から取得して下さい。一時的にサイトの場所を変える時にこの値を設定します。||
|304|Not Modified指定したファイルは変更されていないのでブラウザのキャッシュのデータを表示してください。|
|401|Unauthorixed 認証に失敗しました。|
|403|Forbidden アクセス権がありません。|
|404|Not Found リクエストしたアドレスのページがありません。|
|500|Internal Server Error スクリプトなどで内部のエラーが発生しています。|
|502|Bad Gateway ゲートウェイが無効なレスポンスを受け取りました。|
|503|Service Unavailable サービスが提供できません。webサーバーに負荷がかかりすぎたときなどに表示されます。|

<参考文献>
> https://itsakura.com/network-http-get-post
go getすると410 Goneのエラーが出る

## 背景
GitHub Enterpriseのリポジトリに作成したリポジトリをgo get仕様とすると、 `410 Gone` のエラーが出た。

```
$ go get git.enterprise.com/repo/package
verifying git.enterprise.com/repo/package@v0.1.1/go.mod:
git.enterprise.com/repo/package@v0.1.1/go.mod: reading
https://sum.golang.org/lookup/git.enterprise.com/repo/package@v0.1.1: 410 Gone
```

sum.golang.org を経由せずにダウンロードしたい。

## intelliJのGoModuleの設定確認
Preference > 言語&フレームワーク > Go Moduleの設定を確認。
プロキシーに「direct」が入ってなかったので入れる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/270608/6df38046-5b94-435d-8739-2ad6f25511fc.png)

## GOPRIVATEの設定をして再度 go get
```
$ GOPRIVATE="git.enterprise.com,direct"
$ go get -u git.enterprise.com/repo/package
```

## intelliJの再起動
わたしは何故かintelliJの再起動までし無いと、IDE上で反映がされませんでしたので再起動をしました。

## 参考
- [intellij で go module の設定を行う](https://ema-hiro.hatenablog.com/entry/2019/04/12/020646)
- [Go 1.13 と 1.14 （Go 2 へ向けて）](https://text.baldanders.info/release/2019/06/next-steps-toward-go-2/)