OmniAICreator/Qiita-1.07M huggingface dataset:
ipv6でsnmpを使う

snmpとsnmptrapをインターネット越しで利用するためのメモ。

- ~~自宅がipv6plusになっているため、ipv4で開放できるポートが限られている。当然well-knownポートは開放不可。~~
 - ~~標準のudp161,udp162以外を使う~~
- ~~ipv6だったらポートは全て開放できる。~~
 - ~~ipv6(udp6)を使う~~

いつのまにか、VPSでipv6が使えなくなっていたので、諦める。

# snmp,snmptrapをipv6で使う

## snmpd(agent側)
snmpdの設定例。

```conf:/etc/snmp/snmpd.conf
#  ipv4 -- all / ipv6 -- all, if restrict on localhost [::1]
agentAddress udp:161,udp6:[::]:161

rocommunity  public 127.0.0.1
# ipv6 community
rocommunity6  public aaa:bbbb:cccc:dddd::/64
rocommunity6  public aaaa:bbbb:cccc:ddddd:eeee:ffff:1111:2222/128
```

## snmpでの問合せ(manager側)
snmpwalkの例

```bash:
# snmpwalk -v2c -cpublic udp6:vm-dmz.hrsk6  .1
# snmpwalk -v2c -cpublic udp6:aaaa:bbbb:cccc:ddddd:eeee:ffff:1111:2222  .1
# snmpwalk -v2c -cpublic udp6:[aaaa:bbbb:cccc:ddddd:eeee:ffff:1111:2222]  .1
```

## snmptrapd

```conf:/etc/snmp/snmptrapd.conf
# snmpTrapdAddr udp:162
snmpTrapdAddr udp:162,udp6:162
````

## snmptrapの発行

```bash:
# snmptrap -v2c -cpublic udp6:host.domain '' systemStats 1 s "TEST TRAP" 
# snmptrap -v2c -cpublic udp6:.... '' systemStats 1 s "TEST TRAP" ; 
# snmptrap -v2c -cpublic udp6:[....]:162 '' systemStats 1 s "TEST TRAP" ; 
````
:162は省略可能。

## FWでもipv6でポートを空ける

# snmptrapを標準以外のポートで受ける

- 標準のudp162以外のポートでsnmptrapを受信しようと設定したが、snmptrapdの起動でエラーになった。selinuxでPermissionDenyされていた。
- selinuxをPermissiveにしてselinuxを再起動

trapは受信しているようだが、traphandleがうまく動いていないよう
Visual Studio Code から VSCodium に環境をコピーする

[VSCodium](https://vscodium.com/) とは、Visual Studio Code の完全OSS版のビルドです。MITライセンスです。
Microsoft のロゴが入っていなかったり、使用状況統計を送信しないなどの違いがあります。
拡張機能やMarketplaceはVSCodeと同じように使えます。

会社の決まりやら、宗教上の理由で VSCode が使えなくなった時に、VSCodium に環境をコピーしましょう。

VSCodium のインストール手順は、私は Chocolatey を使っているのでコマンドで一発でした。

```
> cinst /y vscodium
```

そうでない人も、別にここで説明する必要があるほど難しくはないでしょう。[Githubのページ](https://github.com/VSCodium/vscodium/releases)へどうぞ

# 設定
Visual Studio Code の設定ディレクトリは、`%APPDATA%\Code\` にあります。
VSCodium の設定ディレクトリは、`%APPDATA%\VSCodium\` です。
中身を全部コピーするだけです。

# 拡張機能
Visual Studio Code の拡張機能ディレクトリは、`%USERPROFILE%\.vscode\` にあります。
VSCodium の拡張機能ディレクトリは、`%USERPROFILE%\.vscode-oss\` です。
中身を全部コピーするだけです。
curlコマンドでアクセストークンを付与し、APIをPOST送信する

いざ動作確認をしようとする時、毎回調べるのでメモ。

```
curl -X POST -H "Content-Type: application/x-www-form-urlencoded" -H "Cache-Control: no-cache" -H "Authorization: OAuth [AccessToken]" -d 'hoge=12345&fuga=abcde' "https://example.com/api/v1/sample"
```
学習記録（５日目）#関数の引数にデフォルト値を設定する#複数の戻り値を指定する#mapメソッド#数値の進数表現#リストとタプル

# 学習内容
* Python基本文法

    * 関数の引数へデフォルト値を指定する
    * 複数の戻り値を指定する
    * mapメソッド
    * 数値の進数表現
    * リストとタプル


## Python基本文法
### 関数の引数へデフォルト値を指定する
引数にはデフォルト値を設定することができる。以下の例では、`showName()`メソッドの三つの引数のうち二つにデフォルト値が設定されており、1つまたは2つの引数だけを指定する形でもメソッドを呼び出すことができる。

~~~python
def showName(name1, name2 = 'Taro', name3 = 'Kota'):
    print(name1)
    print(name2)
    print(name3)

print('ーーーーー')
showName('Hanako', 'Sachiko', 'Kazuko')   # (1)
print('ーーーーー')
showName('Yuta', 'Ryo')   # (2)
print('ーーーーー')
showName('Chisato')   # (3)
print('ーーーーー')
showName('Hiroki', name3 = 'Yuji')   # （４）
~~~
実行結果
>ーーーーー
>Hanako
>Sachiko
>Kazuko
>ーーーーー
>Yuta
>Ryo
>Kota
>ーーーーー
>Chisato
>Taro
>Kota
>ーーーーー
>Hiroki
>Taro
>Yuji

（１）引数を3つ指定したときはデフォルトの値は用いられない
（２）引数を2つしか指定しなかったときは3つ目の引数はデフォルト値のまま処理が実行される
（３）引数を1つしか設定しなかったときは2つ目と3つ目の引数がデフォルト値のまま処理が実行される
（４）もし、二つ目の引数だけデフォルト値を保持して、1つ目と3つ目の引数を指定してメソッドの処理を実行したいときはこのように明示的に引数を指定すれば良い

### 複数の戻り値を指定する
`return`文で戻り値を指定する際に、カンマで区切って複数の戻り値を返すことができる。このようなメソッドが返す戻り値の型は_タプル_であるため、`for`文でも使うことができる
##### 記述例

~~~python
def twice(num1, num2):
    num1 *= 2
    num2 *= 2
    return num1, num2

for n in twice(10, 25)
    print(n)
~~~
実行結果
>20
>50

### `map`メソッド
引数に別のメソッドとイテレータブルなデータをとり、そのメソッドの処理をデータの各要素に適応させるイテレータを返す。
##### 記述例

~~~python
def twice(num):
    return num*2

a = [1, 2, 3]

b = map(twice, a)

for n in b:
    print(b)
~~~
実行結果
>2
>4
>6

### 数値の進数表現
`0b`を先頭につけることで2進数表現、`0o`で8進数表現、`0x`で16進数表現の数値となる。
##### 記述例

~~~python
a = 0b1100   # 2進数で12
b = 0o17   # 8進数で15
c = 0x2B   #16進数で43
~~~

### リストとタプル
可変個数のデータを格納できるデータ型で、格納されるデータは順序づけされている。リストはデータの個数を増減させたりできるのに対して、タプルはデータを作成後はその内容を変更することができない。

||リスト|タプル|
|---|---|---|
|データの追加| ○ | × |
|データの取り出し| ○ | ○ |
|データの挿入| ○ | × |
|データの削除| ○ | × |

##### 記述例
~~~python
# リストの操作
a = [0, 1, 2, 3, 4]
a.append(6)            # 最後にデータを追加
print(a)

a.extend([7, 8, 9])    # 最後にリストのデータを追加
print(a)

a.insert(5, 10)        # インデックス５の位置にデータを追加
print(a)

del a[5]               # インデックス５のデータを削除
print(a)

b = a.pip(7)           # インデックス７のデータを取り出してbに代入
print(a)
print(b)

c = a.pip()            # 最後のデータを取り出してcに代入
print(a)
print(c)

a.remove(2)            # 値が2のデータを削除
print(a)
~~~
実行結果
>[0, 1, 2, 3, 4, 6]
[0, 1, 2, 3, 4, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 10, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 6, 7, 9]
8
[0, 1, 2, 3, 4, 6, 7]
9
[0, 1, 3, 4, 6, 7]

これ以外にもデータの総数を数える`count()`、データを整列させる`sort()`、データの順番を反転させる`reverse()`、データのコピーを実行する`copy()`、データを全削除する`clear()`などのメソッドはリストに対してのみ使用することができる。
[Django]プロジェクト作成時にやること（いわゆるベストプラクティス）

# はじめに
Djangoのプロジェクトを作成した際に、いつも（自分が）実施している「定型作業」をまとめたものです。
（備忘録的に作成していますので、あくまで参考程度にご覧ください。）

### プロジェクトの作成

```
$ mkdir hogehoge
$ cd hogehoge
$ django-admin startproject config . ←最後のピリオドを忘れないこと
```
以下の様なフォルダ構成になる。

```
hogehoge
├── config
│   ├── __init__.py
│   ├── asgi.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
└── manage.py
```
config以下にプロジェクトの設定ファイルが格納される。

### setting.pyの修正

タイムゾーン及び言語コードを修正する。

```python:config/setting.py

LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'
```

ここでmigrateしておく。

```
$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying sessions.0001_initial... OK
```

ここでサーバーを起動して、ブラウザから
http://127.0.0.1:8000/
にアクセスして日本語の画面になっていることを確認する。

<img width="983" alt="スクリーンショット 2020-03-16 20.11.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287413/84c50313-91c6-6268-3381-f77bc223c32b.png">

### templateファイルを格納するディレクトリを用意する
複数のアプリを開発する時、ファイル名が被ると面倒なのでアプリ単位で
格納先を分けて管理する（以下の様なイメージ）。

```
── templates
    ├── app1
    │   ├── create.html
    │   ├── index.html
    │   └── update.html
    ├── app2
    │   ├── index.html
    │   └── update.html
    └── base.html
```
コンソールからtemplatesディレクトリを作成し、

```
$ mkdir templates
```

setting.pyに格納先を反映する。

```python:config/setting.py
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],  # この行を修正する
        'APP_DIRS': True,
```

### staticファイル格納ディレクトリを用意する
templateファイルと同様に、staticファイルもアプリごとに格納できる様にディレクトリを分ける。
以下の様なイメージ

```
├── static
│   ├── css
│   │   ├── app1
│   │   └── app2
│   └── images
│       ├── app1
│       └── app2
```

コンソールからstaticディレクトリを作成する。


```
$ mkdir static
```
setting.pyに格納先を反映する。

```python:config/setting.py
PROJECT_NAME = os.path.basename(BASE_DIR) #この行を追加

STATICFILES_DIRS = [os.path.join(BASE_DIR, 'static')]　#この行を追加
STATIC_ROOT = '/var/www/{}/static'.format(PROJECT_NAME) #この行を追加

STATIC_URL = '/static/'
```
セキュリティマネジメントの勉強-リスク分析と評価

#リスク分析と評価
リスクマネジメントを行うためには、情報資産を調査し分類する必要がある。
それを情報資産台帳にまとめる。

##情報資産の調査
ISMSの適用範囲で用いられている情報資産の調査を行う。
部門ごとに漏れの内容にリスクを洗いだす。
過去の事件や事故、損害額なども考慮し、脅威と脆弱性を認識する。

##情報資産の重要性による分類と管理
単独で管理すると分析がつらい。
そのためグループ化して管理する。

##情報資産台帳
機密性や重要性、分類グループなどをまとめたのを情報資産台帳という。
情報資産をもれなく記載するだけでなく、変化に応じて適切に更新していくことも必要。

#リスクの種類
##リスク
リスクとはまだ起きてはないが、起こると情報資産に影響を与える事象や状態のこと。
すでに起こったことはリスクではなく問題として処理する。
また起こっていない、起こるかどうかが不確実なことを、リスクとして洗い出す。


##リスク源
リスク発生源（リスクソース）を除去することが有効なリスク対策となる。

##リスク所有者
リスクを洗い出し、リスクとして特定したら、リスク所有者を決定する必要がある。
リスク所有者とは、リスクの運用管理に権限をもつ人。
実質的には組織の役員やスタッフが該当する。

##リスクの種類
| リスク名       |       内容 | 
|:-----------------|:------------------|
|財産損失|火災リスク、地震リスク、盗難リスクなど|
|収入減少|信用やブランドを失った結果、収入が減少するリスク|
|責任損失|製造物責任や知的財産権侵害などで賠償責任を負うリスク|
|人的損失|労働災害や新型インフルなど、従業員に影響を与えるリスク|

ほかにもSNSハザードとかある。
サプライチェーンリスクは、委託先。を含めたどこかで問題が起きたときに受けるもの。
モラルハザードは保険に加入している。が故に、リスクを伴う行動をとってしまうこと。
オペレーショナルリスクは、業務活動に関連するリスクの総称。


##リスク定量化
重要性の判断のため、金額などで定量化する必要がある。
手段としては年間損失額の算出とか、得点法などある。

##リスクマネジメントとリスクアセスメントの違い
情報セキュリティマネジメントでは、リスクに関して組織を指揮し、管理する。
そこで行われるのがリスクアセスメントやリスク対応である。
リスクマネジメントはPDCAサイクルの一連のプロセスだが
リスクアセスメントはPDCAのPに該当する部分である。

##リスク基準
情報セキュリティリスクアセスメントを実施するための基準をリスク基準という。
重大性を評価するための目安とする条件で、アセスメントの実施者によってブレがでないように設定しておく判断指標。
対策を実施するかどうかを判断する基準は、リスク受容基準という。

##リスクアセスメントのプロセス
1:リスク特定
リスクを発見して認識し、記述する。

2:リスク分析
特定したそれぞれのリスクに対し、情報資産に対する脅威と脆弱性を考える。
リスクの発生確率を求め、実際にリスクが起こった時の影響の大きさを考える。
大、中、小みたいな相対評価も多いが、金額で算出することもある

定性的リスク分析・・・金額以外で分析する
定量的リスク分析・・・金額で分析する


3:リスク評価
分析したリスクに対し、どのような対策を行うかを判断するのがリスク評価。
リスクが受容可能どかうかを決定するために、分析結果を基準と比較する。
そして評価基準などから評価し、優先度をつけていく。

##リスク選考とリスク忌避
リスク選考(risk appetite)とは、リスクのある取引などを行うこと。
リスク忌避(risk aversion)とは、リスク回避のため取引などを行わないこと。

##リスクレベル
リスクレベルは優先度のこと。
重大度（重篤度）と発生の可能性というマトリクスで決まる。

| ↓可能性　重大度→|       重大 |   中程度   |軽度|
|:-----------------|:------------------:|:------------------:|:------------------:|
|高い|III|III|II|
|可能性がある|III|II|I|
ほとんどない|II|I|I|

##リスク分析の手法
リスク分析の代表的な手法には、次のようなものがある。
1:ベースラインアプローチ
既存の標準や基準をベースラインとして、組織の対策基準を策定してチェックする。

2:非形式的アプローチ
コンサルタントや担当者の判断で行う。

3:詳細リスク分析
情報資産に対し、資産価値、脅威、脆弱性、セキュリティ要件などを詳細に識別子、評価していく手法。
具体例としては、JRAM(JIPDEC Risk Analysis Method)がある。
JRAM2010年度版もあるらしい。

4:組み合わせアプローチ
複数のアプローチを併用する手法。

#情報セキュリティリスク対応
##リスク対応の考え方
大きく分けるとリスクコントロールとリスクファイナンシングがある。
リスクコントロールは何らかの行動による対応、リスクファイナンシングは資金面で対応することを示す。

リスクが起きたときに、その被害を回避する、または軽減するように工夫することをリスクヘッジという。
リスクが顕在化したときに備えて、情報化保険(IT保険)を利用する方法もあれば、IT事業者向けの賠償責任保険や個人情報漏洩に特化した保険なども用意されている。

##リスク対応の方法
リスクを評価した後で、それぞれのリスクにどのように対応するかを決めていく。
リスク対応にはいろんな方法があり、排他ではないが、適切ではない状況もある。

1:リスクテイク
機会追及のためにリスクをとる、または増加させる。
一般的なリスクを減らすようなセキュリティ対策はこれにあたり、最適化、低減、強化ともいわれる。

2:リスクの回避
リスク源を除去する、つまりリスクを生じさせる活動を開始または継続しないと決定することにより、リスクを回避する。
たとえばMLの運用をやめるとか。

3:リスクの共有（移転、分散）
他者とリスク共有する。
保険を掛けるなどで、リスク発生時の費用負担を外部に転嫁するなどの方法がある。

4:リスクの保有（受容）
情報に基づいた意思決定によって、リスクを保有することを受け入れる。
具体的には何もしない対応を指す。
リスク受容プロセスでは、リスク所有者の承認が必要になる。

##残留リスク
リスク対応後に残るリスクを残留リスクという。
あるリスクに対してリスク対応をした結果、残るリスクの大きさのことを指す。
残留リスクを明確にし、そのリスクが許容範囲かどうかをリスク所有者が再度判断する必要がある。

##リスク対応計画
リスク対応系アックは、それぞれのリスクに対して脅威を減少させるためのリスク対応の方法をいくつか策定するプロセスである。
計画作成時には特定したリスクをまとめたリスク登録簿を作る。
そのあと、各リスクに対する戦略を考え、リスク登録簿を更新する。

##リスクコミュニケーション
リスクコミュニケーションは、リスクに関する正確な情報を企業の利害関係者（ステークホルダ）間で共有し、相互に意思疎通を図ること。
特に災害など、重大で意識の共有が必要なリスクについて行われる。
【MySQL】Geometry型を使って地点間の距離を求める

# はじめに

[前回の記事](https://qiita.com/nkojima/items/bb21c72858606dedd817)ではGeometry型を使ったテーブルを作った後、データの登録と簡単な検索をした所で終わっていました。
今回はGeometry型を活用して、地点間の距離を求めたいと思います。

# 使用した環境

前回の記事と同一の環境となります。

* OS
 * CentOS7.7（1908）
* RDBMS
 * MySQL8.0.19

# 使用したデータ

[前回の記事](https://qiita.com/nkojima/items/bb21c72858606dedd817)で作成した[テーブル](https://qiita.com/nkojima/items/bb21c72858606dedd817#%E3%83%86%E3%83%BC%E3%83%96%E3%83%AB%E3%81%AE%E4%BD%9C%E6%88%90)と[データ](https://qiita.com/nkojima/items/bb21c72858606dedd817#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E7%99%BB%E9%8C%B2)を利用しました。

# 指定した地点間の距離を求めるSQL

* 以下のSQLでは、`ST_Distance`関数を使って2点間の距離を求めています。
* `ST_Distance`関数とよく似た名称の`ST_Distance_Sphere`関数がありますが、[リファレンスマニュアル](https://dev.mysql.com/doc/refman/8.0/en/spatial-convenience-functions.html#function_st-distance-sphere)には**「一般的な用途の距離計算にはST_Distance関数を参照してください」**と書いてあるので、一般的な用途では`ST_Distance`を使えば良さそうです。

```sql:SQL
SELECT
  CONCAT(st1.name, '-', st2.name) AS 区間,
  ST_Distance(st1.location, st2.location) AS '距離(m)'
FROM
  station AS st1,
  station AS st2
WHERE
  st1.name = '東京'
  AND st2.name = '新宿';
```

```text:実行結果
+---------------+-------------------+
| 区間          | 距離(m)           |
+---------------+-------------------+
| 東京-新宿     | 6053.612945828571 |
+---------------+-------------------+
```

# 指定した地点から距離の近い順に並べるSQL

* 以下のSQLでは、東京駅から近い順に駅を並べて取得しています。
* 抽出した列に日本語で別名を付けているため、並べ替えをする際に指定する列名にバッククォート（`）を付けています。
 * 実はこれが分からなくて一番苦労しました...

```sql:SQL
SELECT
  CONCAT(st1.name, '-', st2.name) AS 区間,
  ST_Distance(st1.location, st2.location) AS '距離(m)'
FROM
  station AS st1,
  station AS st2
WHERE
  st1.name = '東京'
  AND st1.id != st2.id
ORDER BY
  `距離(m)` ASC;
```

```text:実行結果
+------------------+--------------------+
| 区間             | 距離(m)            |
+------------------+--------------------+
| 東京-新橋        | 1828.3847670426867 |
| 東京-四ツ谷      |  3368.720839511702 |
| 東京-上野        | 3708.4275968908173 |
| 東京-日暮里      |  5208.928929258798 |
| 東京-新宿        |  6053.612945828571 |
| 東京-品川        |  6350.878230165294 |
| 東京-渋谷        |  6455.104217184891 |
| 東京-池袋        |  7424.298478701934 |
| 東京-大崎        |  7733.106194261948 |
| 東京-北千住      |  8319.038187430975 |
| 東京-赤羽        | 11484.835519176353 |
| 東京-蒲田        | 13975.635963846811 |
| 東京-三鷹        |  18813.40814197637 |
| 東京-立川        | 32051.382378005477 |
| 東京-八王子      |  38789.35456665789 |
+------------------+--------------------+
```

# 指定した地点の最近隣の地点だけを取得するSQL

* 以下のSQLでは、東京駅から最も近い駅を取得しています。
* 上記の「指定した地点から距離の近い順に並べるSQL」とほぼ同じですが、`LIMIT`句を使って抽出結果を上位1件だけに絞り込んでいます。

```sql:SQL
SELECT
  CONCAT(st1.name, '-', st2.name) AS 区間,
  ST_Distance(st1.location, st2.location) AS '距離(m)'
FROM
  station AS st1,
  station AS st2
WHERE
  st1.name = '東京'
  AND st1.id != st2.id
ORDER BY
  `距離(m)` ASC
LIMIT 0,1;
```

```text:実行結果
+---------------+--------------------+
| 区間          | 距離(m)            |
+---------------+--------------------+
| 東京-新橋     | 1828.3847670426867 |
+---------------+--------------------+
```
Pythonで毎日AtCoder #7

### はじめに
[前回](https://qiita.com/taxfree_python/items/063b6a376e64e2db940b)
今日で一週間です。

### #7
[問題](https://abc042.contest.atcoder.jp/tasks/abc042_b)

**考えたこと**
Pythonのsortは文字列に対してもできることを知ったので、sortします。全ての文字列の長さが同じなので、sortしたものをそのまま繋げるだけです。

```python
n, l = map(int,input().split())
s = [input() for _ in range(n)]

s.sort()
ans = ''
for i in range(n):
    ans = ans + s[i]
print(ans)
```

### まとめ
最短の解説になった気がする。文字列を操作する系の問題は苦手なので、精進したい。
では、また
Browser/Node.js両対応、シンプルなHTTPクライアント"bent"

Node.jsでHTTPリクエストしたいなーと思って一番メジャーそうな [request - npm](https://www.npmjs.com/package/request) を覗いたら **deprecated** になってるじゃないですか！

代わりに、シンプルなHTTPクライアントで良いの無いかなーと調べてたら、`request`のissuesコメントにあった`bent`というクライアントに辿り着きました。

# bent
- [bent - npm](https://www.npmjs.com/package/bent)

使い方はとても簡単。

`localhost:3000`へ`GET`してレスポンスボディを文字列で受けたい場合...

```js
const bent = require("bent");

const httpGet = bent("http://localhost:3000", "GET", "string");

const responseBody = httpGet("/");
```

これだけ。

Node.jsでは`http`を、Browserでは`fetch`というように内部で使い分けてるので、コードを統一しつつNode.jsで実行時にはCORS問題が発生しません。
iosアプリリリースまでにお世話になった記事

##Archivingする前に
長時間待った挙句容量不足でできません！ってなりました
https://qiita.com/y-some/items/27cecfc5c7ed5725587c
前もってしておくことをお勧めします！

```
sudo rm -rf ~/Library/Developer/Xcode/iOS DeviceSupport/
sudo rm -rf ~/Library/Developer/Xcode/DerivedData
```
これだけでもだいぶましになると思います

##Provisioning profile "XXXXXX" doesn't include signing certificate YYYY って出る
https://qiita.com/warapuri/items/2a32cb2201ce75aa5f4b#4-%E5%86%8D%E8%B5%B7%E5%8B%95

##simulatorだと問題ないのに実機だと落ちる
https://qiita.com/edo_m18/items/dbf720b1964f7cd5e9b9


> 設定アプリ > プライバシー > 解析 > 解析データ

これで自分の開発したアプリ名のログをみてみましょう。
自分の場合は

```
thread0 crashed with arm thread state
```

というのを発見して

https://stackoverflow.com/questions/54427407/thread-0-crashed-with-arm-thread-state-64-bit
こちらの記事から　
自分は全ての手順を踏む前に解決できました。強制アンラップを疑ったところ無事直りました!
MacからYAMAHAルータのCOMポートに接続する

# はじめに

色々ある世の中…いざというときのために、今使っているMacからYAMAHAルータのCOMポートに
接続する手段は確保しておきたいな…と思い、ちょっと調べました。

*いざというとき＝たとえば、ルータの設定書き間違えて、ネット越しにルータに入れなくなったとき（こわっ！）*


# 準備したもの

**シリアル(RS232C) - USB変換ケーブル**
とりあえずFTDIチップセット内蔵の[こいつ](https://www.amazon.co.jp/gp/product/B075YGKFC1/)を入手しました。
![IMG_8206.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128331/4201215d-3b44-1b75-8175-cbb4ba620e9a.jpeg)

**MacBook Pro**
今使っているマシン。（macOS 10.15）
最近「A」のキーが陥没気味。

**YAMAHAルータ（RTX1200）**
絶賛稼働中。
![RTX1200.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/128331/c0939b04-9fba-ec24-9829-732a3175b8e7.jpeg)


# 作業手順

まずは、シリアルUSB変換ケーブルでMacとルータを接続し、Macでターミナルを立ち上げます。

デバイス名を確認します。

```bash
$ ls /dev/tty.*
```

`tty.usbserial-********` が対象のデバイス名になります。

Macではscreenコマンドが入っているのでありがたく使わせてもらいます。

```bash
$ screen /dev/tty.usbserial-********
```

これでターミナルからCOMポートに接続できます。

```bash
Password:
```

とルータのログイン画面が表示されます。
いつも使っているルータパスワードを使ってログインし、作業します。
もしルータパスワードを忘れてしまったとか、非常事態の場合は緊急用のパスワード `w,lXlma` で…。

screenから抜ける時は、Ctrlキーを押したまま「A」キー、「¥」キーの順に押すと、
`Really quit and kill all your windows [y/n]` と表示されるので、y を入力します。

# おわりに

実際に活用することはほぼ無いかも知れませんが、
保険だと思って、原始的な手段は1つくらい確保しておいたほうがいいですね。
Cloud9のワークスペースに入れなくなった時の対処法と最終手段

無事ワークスペースに入れなくなったあなた、この記事を読む前に
https://qiita.com/somarihair/items/759d525153ae68ce4a7f
https://qiita.com/Atsushi_/items/b38c18feac4708164696
この2つの記事を先に読むことをお勧めします。

#起こった問題#
Chromeを起動して最初にワークスペースにアクセスしようとすると
>This is taking longer than expected. If you think there might be an issue, contact AWS Support.
It might be caused by VPC configuration issues. Please check documentation.

または

>This is taking longer than expected. If you think there might be an issue, contact AWS Support.

とエラーメッセージが表示され、上記の記事のようにインスタンスページに行くと
>インスタンスデータ You are not authorized to perform this operation. の取得中にエラーが発生しました。

と表示される。
検証ページのコンソールには
>Access to XMLHttpRequest at '{リンク}' from origin 'https://ap-northeast-1.console.aws.amazon.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.

そして
>ERROR Error: Failed to retrieve resource from {リンク} with code 0
    at XMLHttpRequest.xhr.onerror (https://d139ht92gga9c6.cloudfront.net/c9-73b98c857618-ide/build/configs/ide/@aws/cloud9/configs/ide/environment-default.js:951:30)

さらに
>Failed to load resource: net::ERR_FAILED

この3つのエラーメッセージが繰り返し表示されエラーが100件近く溜まる。

#対処法#
本質的な解決方法は最初の2記事を見る、そして[AWSトラブルシューティング](https://docs.aws.amazon.com/ja_jp/cloud9/latest/user-guide/troubleshooting.html)に載っている通り管理者に問い合わせることです。

僕の場合はどちらも効果がなかったのでどちらかというと回避策的な方法を2つ書いておきます。
1. Chromeのアカウントを変えてアクセスする。
2. Safari等他のブラウザからアクセスする。

今回の問題の根本が何かはわかりませんでしたが、アカウントのcookieやキャッシュ削除でも意味を為さなかったあたり、Chrome自体に問題があったようです。
【基本情報技術者試験】木構造、アルゴリズムの用語一覧

【注意】
備忘録、自らのアウトプット用です。

木構造の用語一覧

線形探索法：先頭から順に目的の値を探す方法。
番兵：終了判定を簡単にするために末尾に配置したデータ。
二分木：節から伸びる枝が2本以下のもの。
二分探索法：ある配列において、半分に分割し、目的のデータと比較して探す方法。
ハッシュ法：ハッシュ関数を使って、データの格納位置を求める探索法。
シノニム：配列の格納位置がダブって衝突すること。


アルゴリズムの話
基本交換法(バブルソート)：隣り合うデータの大小を比較して並び替えて整列させる方法。

基本選択法：対象のデータ群から最小のデータを取り出し先頭のものと交換。
これを繰り返して整列させる方法。

基本挿入法：対象のデータ群から整列している部分とそうでない部分を分け、未整列の部分からデータを一つずつ取り出し、整列している部分に挿入して整列させる方法。


高度なアルゴリズム

シェルソート：一定間隔で取り出した部分をそれぞれ整列させて元の配列に戻す。
これを繰り返し、取り出す間隔が1になるまでやる方法。

クイックソート：大体の中央値を決め、それより大きいグループと小さいグループに振り分ける。
それぞれのグループで先述の手順を繰り返して整列させる方法。

ヒープソート：配列の中から未整列の部分を順序木という二分木を構成し、そこから最小値ないし最大値を取り出して整列済みの配列へ配置することを繰り返す方法。

参考・出典：キタミ式イラストIT塾基本情報技術者　令和二年
Vagrant上にローカルからファイルをコピー（scp）

## ファイルのコピー
コマンドの実行場所はVagrant上ではなく、ローカルで実行。


```:ローカルからVagrant上へコピーの場合
$ scp /Users/user-name/Desktop/hoge.txt vagrant@web1:/www/file/
```
【構文】scp <font color="DarkGreen">コピー元パス</font> vagrant@<font color="Magenta">VMホスト名</font>:<font color="Blue">コピー先vagrant上のパス</font>

↑↑これでローカルの「<font color="DarkGreen">/Users/user-name/Desktop/hoge.txt</font>」を、
<font color="Magenta">Vagrant（web1バーチャルマシン）</font>上の
「<font color="Blue">/www/file/</font>」ディレクトリにコピーする。


```:Vagrant上からローカルへコピーの場合
$ scp vagrant@web1:/www/file/hoge.txt /Users/user-name/Desktop/
```



#### VMホスト名はVagrantfileの`vm.hostname`を参照。

```:Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.define "default" do |web1|
    web1.vm.box = "mvbcoding/awslinux"
    web1.vm.hostname = "web1"
    web1.vm.network "private_network", ip: "xxx.xxx.xxxx"
  end
```


## ディレクトリのコピー
`-r` オプションをつけると、ディレクトリごとscpできる。

```:hogeディレクトリをvagrant上にコピー
$ scp -r /Users/user-name/Desktop/hoge vagrant@web1:/www/file/fuga/
```

以上。
【Eclipse】JUnitの実行結果（テスト実行レポート）を出力する

Eclipseで、JUnitの実行結果（テスト実行レポート）を出力する方法です。

## 環境
- OS：Windows10
- Eclipse：Neon

## 手順
1.JUnit実行後、「JUnit」タブで「テスト実行ヒストリー」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/d58d236a-aa83-c567-8d51-de69c8eb9e8c.png)

2.テスト結果レポートを出力したいものを選択し（①）、「エクスポート」をクリック（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/5d3067d1-226e-a062-c139-d96e92245b99.png)

3.「テスト実行のエクスポート」ウィンドウが開くので、ファイル名を確認し、任意の場所にて、「保存」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/fb2c5ad2-e35c-bea0-285f-456a3bf1eed2.png)

## 補足事項
### XXXTest(n)（「XXXTest」はテストクラス名、「n」は番号）とテスト実行レポートに採番されてしまう場合の対処法
例えば、テストクラス名がPracticeTest.javaだった場合に、テスト実行レポートの名称が、PracticeTest(1) yyyymmdd-hhmmss.xmlの「(1) 」のように採番が入ってしまうケースがあります。
この事象は、ディレクトリ違いで同じ名称のテストクラスが存在する場合に発生します。

不具合ではないので、気にならなければそのままで大丈夫ですが、以下の手順により解消できます。

1.テストクラスを開き、クラス名の上で右クリック（①） > 「デバッグ」（②） > 「デバッグの構成」（③）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/b36d229e-0fbc-9b1e-492f-798d93bf7d6e.png)

2.JUnit配下の同名のテストクラスを選択し(①)、「選択された起動構成の削除」をクリック（②）。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/356958/0bb37114-7564-58ba-d541-a4fcf4793480.png)

3.この後、テスト実行レポートのエクスポートを行えば、(n)は消えています。
PowerShell 選択肢GUI表示

# ■概要

PowerShellでGUIの選択肢を表示する方法。
![00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/a4f13368-7941-5b38-7e41-fcc411a03efa.png)

# ■環境

* Windows 8.1 / PowerShell 4.0
* Windows 10 / PowerShell 7.0

# ■コード

```PowerShell
Add-Type -AssemblyName PresentationFramework

# 画面定義
[xml]$xaml = @'
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Title="選択"
  Width="300" Height="200" ResizeMode="Noresize">
    <Window.Resources>
        <!-- 共通スタイル定義 -->
        <Style TargetType="RadioButton">
            <Setter Property="Margin" Value="5"/>
        </Style>
        <Style TargetType="Button">
            <Setter Property="Margin" Value="10"/>
            <Setter Property="Width" Value="100"/>
        </Style>
    </Window.Resources>

    <Grid FocusManager.FocusedElement="{Binding ElementName=firstRadio}">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <StackPanel Name="radiosContainer">
            <TextBlock Text="以下の選択肢から好きな果物を選択してください。" Margin="5"/>
            <RadioButton Content="リンゴ" Name="firstRadio" IsChecked="True"/>
            <RadioButton Content="キウイ"/>
            <RadioButton Content="パイナップル"/>
        </StackPanel>

        <StackPanel Orientation="Horizontal" Grid.Row="1">
            <Button Content="OK" Name="okBtn" IsDefault="True"/>
            <Button Content="キャンセル" Name="cancelBtn" IsCancel="True"/>
        </StackPanel>
    </Grid>
</Window>
'@

$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)

$radios = $window.FindName('radiosContainer')
$okBtn = $window.FindName('okBtn')
$cancelBtn = $window.FindName('cancelBtn')

[string]$script:selectedRadio = ''

# OKボタン押下時の処理
$okBtn.add_Click.Invoke({
    foreach ($item in $radios.Children) {
        if ([string]$item.GetType() -ne 'System.Windows.Controls.RadioButton') {
            continue
        }
        if ($item.IsChecked) {
            # 選択されたラジオボタンのContentを保存
            $script:selectedRadio = $item.Content
            break
        }
    }
  # ウィンドウを閉じる
  $window.Close()
})

# キャンセルボタン押下時の処理
$cancelBtn.add_Click.Invoke({
  # ウィンドウを閉じる
  $window.Close()
})

# ウィンドウ表示
$window.ShowDialog() > $null

# 結果表示
if ($selectedRadio) {
    Write-Host "${selectedRadio}が選択されました。"
} else {
    Write-Host "キャンセルされました。"
}
```

# ■実行イメージ

![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/02d684ef-5006-96aa-dc58-483e8d62ef6f.png)

ラジオボタンを選択し、OKボタンを押すと選択したものが表示される。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/142879/0a8cf9dd-7254-32c6-02c4-0fb1a2e39d47.png)

# ■補足
CUIでやる場合は`$Host.UI.PromptForChoice`
Python Matplotlibの動作確認用コード

手早く手元でmatplotlibの動作確認をしたいとき向けの短いコード

## サンプルコード

```python:sample
import matplotlib.pyplot as plt

plt.plot([1,2,10,18,19,20])
plt.show()
```
## 結果

![Figure_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/126628/fab8befb-36ee-0ff2-c74d-d2605a156a9a.png)
セキュリティマネジメントの勉強-情報セキュリティ継続

#情報セキュリティ継続
##緊急事態の区分
緊急事態の区分を明らかにしておく必要がある。


| レベル       |事象 |
|-----------------:|:------------------:|
| 1       |       影響を及ぼすおそれのない事象 |
| 2       |       影響を及ぼすおそれの低い事象 |
| 3       |       影響を及ぼすおそれの高い事象 |

##緊急時対応計画
Contingency Plan
サービスの中断や災害発生時に、システムを迅速かつ効率的に復旧させる計画。

初期の対応計画では、初動で何をするかなどを中心に組む。
完全復旧よりも暫定対応を優先することもある。

##復旧計画
緊急対応後、完全復旧させるための計画です。
暫定的ではなく、恒久的な復旧を目指す。

##障害復旧
日頃からバックアップを取っておくこと。
バックアップデータはシステムのそばに置いてるほうが復旧が早いが
地震とかの大災害時を想定すると、遠隔地に保存しておくことも必要。

##ディザスタリカバリ
事業継続マネジメントのおける概念の一つ。
災害などによる被害からの回復措置や、被害を最小限に抑えるための予防措置などのことを指す。

|略称       |意味 |
|:-----------------|:------------------:|
|RTO(Recovery Time Objective:目標復旧時間)|災害発生からどれくらいの時間以内にシステムを再稼働しなければならないかを示す|
|RPO(Recovery Point Objective:目標復旧時点)|システム再稼働時にどの時点の状態まで復旧しなければならないかを示す|
これを前提にバックアップシステムを作る。

##サポートユーティリティ
装置のライフラインに関する管理策。
サーバ室の停電とか消火とかそういうの。
JIS Q 27002:2014(情報セキュリティ管理策の実践のための規範)
警報装置を取り付けることや、定期検査を行うことなどの管理策が定められている。
【Go】MySQLのTimestamp型カラム（日本時間が入ってる）をtime.TimeにするとUTCになってしまうのを対応する

こんにちは:smiley:

MySQLのTimestamp型カラムに`2020-03-12 15:00:00`（日本のおやつの時間！）が入っていて、それをGo言語のコードで`time.Time`型として取ってくると`"2020-03-12 15:00:00 +0000 UTC"`になってしまう。

あるとおもいます。

それを期待通りの値に直す小ネタです。

```例.go
…
	tempTime := dbResults[0].CreatedAt
	location := time.FixedZone("JST", 9*60*60)
	tempTime = tempTime.In(location).Add(-9*time.Hour)
	log.Print(tempTime)
```

* 強引に`JST`に変換します。
* そのとき勝手に9時間足されてしまうので、自前で引き直します。

↓

```bash
2020/03/16 19:44:57 2020-03-12 15:00:00 +0900 JST
```

やったぜ。
同ホスト内にテストサイトを量産したい時のApacheとDNSの設定

うまく設定するとテストサイトの量産が簡単にできるようになったのでメモ

# DNS

Aレコードのサブドメインに `*` を指定できる。
例えば `*.test.example.com` のように設定すると、 `hoge.test.example.com` などでアクセス可能となる。
`*` は先頭のみ可能で、途中に記載してもアクセスできなかった。

# Apache

ApacheのVirtualDocumentRootの設定には変数を利用できる。
以下のように設定すると、 `hoge.test.example.com` でアクセスが来た時に `/var/www/html/hoge` がDocumentRootとなる

```conf
<VirtualHost *:80>
    ServerName test.example.com
    ServerAlias *.test.example.com
    VirtualDocumentRoot "/var/www/html/%1"
</VirtualHost>
```

# インストールスクリプトを作成する

以下はEC-CUBEをインストールする例。

```shell
#/bin/bash

if [ $# != 1 ]; then
    echo "引数の数が間違っています！"
    exit 1
fi

SITE_NAME=$1

BASE_DIR=/var/www/html
SITE_DIR=${BASE_DIR}/${SITE_NAME}

REPOSITORY=https://github.com/EC-CUBE/ec-cube.git
TAG=4.0.3

git clone --depth 1 --branch=${TAG} ${REPOSITORY} ${SITE_DIR}

cd ${SITE_DIR}

/usr/local/bin/composer install
bin/console eccube:install --no-interaction
```
AWS CLIでアカウントIDとリージョンを取得する



EC2上でシェルを書く時、何かとAWS CLIでリージョンやアカウントIDを使うことが多いですよね。

ただ、そのままアカウントIDを`111222333444`のように埋め込んだり、リージョンを`ap-northeast-1`と書くのは、様々な環境で使い回す上ではなるべく避けたいと思ったので取得してみました。

## アカウントIDの取得方法

アカウントIDは`aws sts get-caller-identity`を使用して取得できます。

```bash
$ aws sts get-caller-identity
{
    "Account": "111222333444", 
    "UserId": "AAAABBBBCCCCDDDDEEEE", 
    "Arn": "arn:aws:iam::111222333444:user/sample"
}
```

このようにAccountやUserID、IAMのARNがJSONで返ってくるので、ここから取得してあげましょう。

先程のコマンドから`jq`を使用してパースして抜き出します。

`jq`がない場合はインストールして下さい。
[参考：jq コマンドの Linux への速攻インストール](https://qiita.com/wnoguchi/items/70a808a68e60651224a4)

```bash
$ aws sts get-caller-identity | jq -r '.Account'
> 111222333444
```

こんな感じでアカウントIDはOK

※2020/03/17追記
CLIの--queryオプションであれば、jqを使用せずとも抜き出せるとコメント頂きました。こちらの方が簡単ですね！

```bash
$ aws sts get-caller-identity --query 'Account' --output text
```

## リージョンを取得する方法

リージョンは以下のコマンドで取得してみます。

```bash
$ curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e s/.$//
> ap-northeast-1
```

インスタンスのメタデータからAZの情報を取得できるので、最後の1文字を削除してあげればリージョン名になります。

## シェルで使用する

AWSではサービスの情報を取得したり、何か情報をPUTしたりする際ARNを指定することが多いんですが、これの中にアカウントIDやリージョンがよく必要になります。

例えばSNSのトピックを指定する際のARNはこんな感じ。
`arn:aws:sns:ap-northeast-1:111222333444:sample-topic`

これは見ればわかると思いますが、
`arn:aws:sns:【リージョン】:【アカウントID】:【トピック名】`

のような法則で作られる文字列です。

シェルの中で変数に入れたい場合はこんな感じに変数で書いてあげましょう。

```bash
SNS_TOPIC_NAME="sample-topic"
REGION=`curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed -e s/.$//` 
ACCOUNT_ID=`echo aws sts get-caller-identity | jq -r '.Account'` 

SNS_TOPIC_ARN="arn:aws:sns:${REGION}:${ACCOUNT_ID}:${SNS_TOPIC_NAME}"
echo ${SNS_TOPIC_ARN}

> arn:aws:sns:ap-northeast-1:111222333444:sample-topic
```
こうすると他のアカウントや別リージョンで同じシェルを使いたい場合でも、トピック名だけを修正すればいいのでとても修正箇所が少なくて済みます。

誰かのお役に立てれば幸いです。
サクラエディタ設定

# フォント
- [Myrica](https://myrica.estable.jp/)
- 設定 > フォント設定

# カラースキーマ
- [拾い物](https://ekafp7.blogspot.com/2018/07/col.html)
- タイプ別設定 > カラー > インポート

# 折り返ししない
- タイプ別設定 > スクリーン > レイアウト > 折り返し方法

# ツールバー非表示
- 共通設定 > ウィンドウ > 基本設定

# タブ設定
- 共通設定 > タブバー > タブバーを表示する
- 共通設定 > タブバー > ウィンドウをまとめてグループ化する
- 共通設定 > タブバー > ウィンドウの閉じるボタンは現在のファイルのみ閉じる
refileのattachment_image_tagで画像がうまく表示されない場合に

#概要
現在スクールにてRailsの学習中で、画像表示にrefileを使用しましたが、正しく記述しているはずなのに上手く表示されず少し苦労したので備忘録も兼ねて対処法をメモします。(スクールのカリキュラムには後半にちゃんと対処法が書いてありましたが、自分が読み飛ばしてしまい、対処に時間がかかってしまいました。)同じ症状の方の助けになれば幸いです。

#環境
OS: macOS Catalina バージョン10.15.3
Ruby: 2.5.7p206
Rails: 5.2.4.1
開発環境：VirtualBox + vagrant

#前提
こちらの記事にある1〜5のインストール・設定・記述は実施しました。
refileの基本的な使い方が良く纏まっていると拝見いたしましたので、引用させていただきます。
[refileの基本と複数画像のアップロード](https://qiita.com/nekosuke_/items/501e7ba1b286c51c1be9)

ちなみにgemのバージョンは
refile 0.6.2
refile-mini_magick 0.2.0
です。

#症状
正しく設定・記述されているはずなのにブラウザ上で以下の様になってしまい、画像がうまく表示されませんでした。

- Chrome<br>

| ![chrome_image_error.png] (https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488358/249417cd-9f88-76b4-ff01-9f85ffa888fc.png) |
|:-:|

- Safari<br>

| ![safari_image_error.png] (https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488358/c9fc3482-6699-a1fe-fbb2-affea96f14b4.png) |
|:-:|


#確認してみたこと、試してみたこと
- データベースの中身の確認

そもそもデータベースのimage_idカラムに保存がされていないのではないかと思い確認。
自分の場合はlistsテーブルにimage_idカラムを設置していたので、

~~~
rails dbconsole
~~~
から

~~~
SELECT * FROM lists
~~~
で全レコードを表示。
image_idカラムを確認しましたが、きちんと文字列が記載されていたのでデータベースへの保存自体はうまくいっている様でした。

- ブラウザの変更

あまり関係ないかもと思いつつ、上記の通りChromeとSafari両方のブラウザで表示状況を確認しましたがどちらも上手く表示されていませんでした。

- 別の拡張子の画像ファイルをアップ

最初に投稿していた画像が.jpgだったので、試しにと思い.pngの画像もアップしてみる。しかしやはり上手く表示されていませんでした。

#原因・解決法
結論から言うとattachment_image_tagの書き方が原因でした。

上記のリンク先にもある通り、自分が見た多くの記事ではviewの記述としては

~~~
<%= attachment_image_tag モデル名, :カラム名(末尾の_idは除く),format: '拡張子名(例: jpeg)', :fill, 横幅の数値(例: 100), 高さの数値 %> 
~~~
が紹介されていましたが、これの`:fill, 横幅, 高さ`の部分が問題だった様です。
自分の場合は以下の記法に変更して画像が表示される様になりました。

~~~
<%= attachment_image_tag モデル名, :カラム名(末尾の_idは除く),format: '拡張子名', size: "横幅数値x高さ数値" %>
~~~
⚠️最後の横幅数値、高さ数値の間の記号は小文字のエックスです。

例：

~~~
<%= attachment_image_tag list, :image, format: 'jpeg', size: "100x100" %>
~~~

これで以下の様に、きちんと表示されるようになりました！

| ![success_image.png] (https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/488358/ff4bbe35-1531-2af6-7d63-f9327c31726a.png) |
|:-:|


#後書き
なぜ`:fill`での指定はダメで`size:`ならいけるのかという原理的な理由は分かりませんでしたが、自分の場合はこれでとりあえず画像がちゃんと表示される様になりました。今後これで進めて行った場合に不具合が出てきたら都度追記していこうと思います。
また、冒頭でも述べた通りスクールのカリキュラム内で、後半にではありましたがきちんと対処法が書かれていました。(自分はそこまでカリキュラムを進めていたので読んでいたはず。)今後は1文字も読み飛ばさず、しっかりと確認しつつ取り組んでいこうと思います！
Lhaplusでパスワードを自動設定して圧縮する

# はじめに

あるプロジェクトでファイル添付の際は、共通パスワードを使うというルールがあり、毎度、Pass付きで圧縮するのが面倒だったので、ファイルを右クリックすると自動的に圧縮できるようにしたので、その備忘です。

正直、使うシーンはあまりないかも。

# 環境
- Windows 10

# 手順
## ①Lhaplusを下記のディレクトリにインストールする
　C:\Program Files (x86)\Lhaplus

　【参考】入手元：https://forest.watch.impress.co.jp/library/software/lhaplus/

## ②バッチファイルを作成する
パスワードをhogefugaで設定する場合の例

```zip.bat
@echo off

:check
if %1=="" goto final
"C:\Program Files (x86)\Lhaplus\Lhaplus.exe" /c:zip /o:.\ /p:hogefuga %1
shift
goto check
:final
```

ちなみにhoge[yyyyMMdd]にしたい場合はこんな感じ。

```
"C:\Program Files (x86)\Lhaplus\Lhaplus.exe" /c:zip /o:.\ /p:hoge%date:/=% %1
```

※インストール時にインストールフォルダを変更した場合は、「"C:\Program Files (x86)\Lhaplus\Lhaplus.exe"」を変更。

## ③zip.batを下記のディレクトリに追加する
　ファイルを右クリックして実行できるようにします。今回は「送る」の中にいれました。
　C:\Users\\[ユーザ名]\AppData\Roaming\Microsoft\Windows\SendTo

## 【補足】Lhaplusのコマンドラインオプション

|オプション|説明|
|---|---|
|/c:[拡張子]|[拡張子]の形式で圧縮する|
|/o:[ディレクトリ]|出力先として[ディレクトリ]を指定する|
|/p:[パスワード]|zip圧縮時に[パスワード]を指定する|

## スクリーンショット
対象ファイルを右クリックし、「送る　＞　zip.bat」から実行可能。
![img.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/21433/f9eb8085-bbd3-29df-5837-c9b351436531.png)
オンライン研究会用タイムキープを自動化してみた

「私達のオンライン天文学会」という研究会をzoomで開催したのですが、座長（質問準備）＋チャット監視＋タイムキープは正直無理でした。時間管理がガバガバに。タイムキープの問題点は以下の通り

- リアルならタイマーアプリでOK
- オンラインだとマイクのミュート操作が必要
- ヘッドセットにベルを近づけても音割れ等が心配

ということで、なんとか時間管理を自動化出来ないかな？とWindowsでシステムを組んでみました。（zoomでの音声テストまではやりました。実用テストはまだ）

ぺぱさんのブログが大変参考になりました。この場にて御礼申し上げます。
[かみぺぱにっき: 生放送や配信にBGMや効果音を入れる！](http://kamipepa.blog.jp/archives/37741701.html)
[かみぺぱにっき: 無料で使える仮想オーディオデバイス集めてみた](http://kamipepa.blog.jp/archives/39365460.html)
[かみぺぱにっき: VOICEROIDでボイスチャットをしたい！](http://kamipepa.blog.jp/archives/37711720.html)

# システム概要
必要なソフトは以下の３つです。

1. 効果音ポンだしくん https://www.vector.co.jp/soft/winnt/art/se499320.html
2. VB-CABLE Driver https://www.vb-audio.com/Cable/index.htm
3. Audio Router https://www.gigafree.net/system/registry/Audio-Router.html

効果音ポンだしくんでベルを鳴らした音をAudio RouterでVB-CABLEに流し、zoom側で受け取る流れです。

## 効果音ポンだしくん 設定
インストールは上記URL先からzipをダウンロードして解凍するだけです。特別なインストールは必要ありません。また同梱のReadMe.txtが説明書になっています。

PonDashiKun.exeを起動したら、まずは「ファイル＞保存」をしてください。
メニューバーの「追加」により音声ファイルの設定ウィンドウが追加されますので、適当な名前（今回はBell）を設定し、任意のファイルを「参照」より指定します。今回は[TAM Music Factory](https://www.tam-music.com/)さんのchiin1.mp3をお借りしました。
![PonDashiKun_Setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264339/a3d8391a-f1e7-d83c-40ab-6a3002906488.png)
メインパネルの時間を「リセット」した上で、イベントトリガーリストの「追加」をします。再生の後ろのボックスに先に設定した名前（今回はBell）とし、タイマー経過時間を設定します。今回は7分で1鈴、9分で2鈴、12分で3鈴を設定しました。

時間管理として使う時はメインパネルの時計が00:00:00になっているのを確認して、イベントトリガーリストの各イベントの左側のチェックボックスに✓してください（この状態で保存していると便利です）。メインパネルの「スタート」を押すと時間が進みだします。再度使う場合は再び✓を入れ直す必要があります。

## VB-CABLE Driver 設定
上記URLよりzipをダウンロードし、その中のインストーラー(VBCABLE_Setup_x64.exe)を管理者権限で実行すればあとは従うだけです。PCの再起動が必要です。

## Audio Router 設定
上記URLよりzipをダウンロードして解凍するだけです。特別なインストールは必要ありません。

Audio Routerを起動してから、効果音ポンだしくんの方でファイルを再生するとリストに表示されます。効果音ポンだしくんの下の▼からRouteをクリックし、VB-CABLEを選択します。効果音ポンだしくんの方でもう一度再生するとリストが更新されます。
![AudioRouter_Setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264339/86849725-9ad1-cca4-2db1-2a6f5cd92973.png)

## zoom 設定
zoomの音声入力元をVB-CABLEに設定するだけです。
![Zoom_VB_Setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264339/01f6454a-ee00-83d1-da14-69dcd0977d5a.png)
「スピーカー＆マイクをテスト」したところベルが鳴ったことを確認できました。ただし高音域がカットされるみたいで、音はベルにこだわらないほうが良いかもしれません。

## 注意点
当システムでは音声と効果音（ベル）を同時に利用することはできません。同時使用には[VoiceMeter Banana](https://www.vb-audio.com/Voicemeeter/banana.htm)を使うと良さそうですが、今回は実装までには至りませんでした（ノイズがひどい）。このサイト（[VoiceMeeter BananaとAudio Routerの併用で音声出力先が自由自在！無料で最強のミキサー環境を作る](https://arutora.com/archives/20180518222003/)）を読み解けば実装できるかもしれません。

# 最後に
新型コロナウィルスにより多くの学会が中止になりました。情報処理学会の企画の様（参考１）にオンライン開催が出来るコミュニティは少ないと思います。オンライン研究会の機会が増えるにつれ、コミュニティ内のデジタルディバイドがより浮き彫りになっていくのではと考えています。

参考１ [バーチャルイベント空間clusterで学会パネルディスカッションの司会をしてみた #clusterVR #IPSJ先生質問です](http://yumulog.hatenablog.com/entry/2020/03/07/175037)

# 追記：マイクも同時に入りました！
「コントロールパネル」＞「ハードウェアとサウンド」＞「サウンド」より、「録音」タブ中にある使用したいマイクのデバイスのプロパティを開き、「聴く」タブ内の「このデバイスを聴く」にチェックを入れ、「このデバイスを使用して再生する:」にてVB-CABLEを選択すればOKです。zoomではマイクをVB-CABLEに設定します。
![Mic_Setup.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/264339/19cacc6b-e0a9-422f-5f66-aed244ee4039.png)

この設定にした場合は自分のマイクを機械的にミュートにすることをお忘れなく。zoomでミュートするとベルまでミュートしてしまいますので。
Vue CLIで作成したindex.htmlからオブジェクトを取得する

## タイトルの内容をもうちょっと詳しく
- Vue CLIで作ったプロジェクト
    - ディレクトリ構成はデフォルトのまま
- 画面表示用にオブジェクトを渡したいが、諸事情によりindex.htmlに書くことしかできない
    - index.htmlに```script```タグを書いて埋め込む
- なのでVue側からindex.htmlに記載された値を取得する

## サンプルコード

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>args sample</title>
    </head>
    <body>
        <div id="app"></div>
        <script>
        var htmlArgs = [
        {
            "key1":"hoge",
            "key2":"fuga"
        },
        {
            "key1":"foo",
            "key2":"bar"
        }
        ];
        </script>
    </body>
</html>
```

```vuejs:App.vue
<template>
  <div id="app">
    <ul>
      <li v-for="arg in args" v-bind:key="arg.key1">
        key1={{arg.key1}} / key2={{arg.key2}}
      </li>
    </ul>
  </div>
</template>
<script>
/* global htmlArgs */
export default {
  name: 'App',
  data: function(){
    return {
      args: htmlArgs
    }
  },
}
</script>
<style>
</style>

```

## 解説
今回のキモになるのは、App.vueの```/* global htmlArgs */```です。
これが無い状態で実行すると、以下のようなエラーとなります。

```terminal:cmd
ERROR  Failed to compile with 1 errors
error  in ./src/App.vue

Module Error (from ./node_modules/eslint-loader/index.js):

C:\Users\anonymous\sample\src\App.vue
  12:34  error  'htmlArgs' is not defined no-undef

✖ 1 problem (1 error, 0 warnings)

```

App.vueの中にhtmlArgsがいないのでエラーになります。
無いものを使おうとしているわけですから、当然ですね。

先ほどの```/* global htmlArgs */```は**htmlArgsはglobalにいる(からファイル内に無くてもスルーしてくれ)と宣言して、エラーを防ぐ**という効果があります。

これでindex.htmlにあるオブジェクトを取得できるようになりました。
めでたしめでたし。


## 参考
[アンビエント宣言が’no-undef’ルールにひっかかる件
https://teratail.com/questions/226017](https://teratail.com/questions/226017)
Raspberry pi,Jetson Nanoでリアルタイム音声信号への機械学習モデルによるエフェクト(Raspberry pi ,Jetson Nano環境構築編)

[前回](https://qiita.com/kmitsu76/items/714258bddde272621518)作成したMyChain.nnpをRaspberry pi ,Jetson Nanoへ転送させて推論させてみる。

まずはRaspberry pi ,Jetson Nano環境へPython推論環境を構築する必要があるが、Armアーキテクチャ向けのパッケージがなく、Windows10 のようにpipコマンドではインストールできない

冗長部分があるかもしれないが、下記の流れでRaspberry pi ,Jetson Nano両方ともセットアップができた。

##前提環境
Raspberry pi 3b+ Raspbian Buster 2020-02-13-raspbian-buster-full.img　Sandisk 128GB SD
Jetson Nano B01リビジョン OSバージョン　r32.3.1　Sandisk 128GB SD

##Raspberry pi 特有の情報：
CPU負荷がかかるタスクで、電源がシビアになるのでRaspberry pi 3b+対応電源を用意すること。
赤い電源ボタンが点滅し、システムログに電力が足りないエラーが出ないように確認する。

NNabla必要パッケージのインストールでメモリが足りないので、下記を参考にスワップを2GBにする。
https://qiita.com/nyas/items/f4d0675061ee8cdcc3e7


##Jetson Nano B01特有の情報：
Pythonが3.6が標準なので、3.7に変更。

sudo apt install python3.7 python3.7-dev
sudo rm /usr/bin/python3
sudo ln -s /usr/bin/python3.7 /usr/bin/python3
cd /usr/lib/python3/dist-packages
sudo cp apt_pkg.cpython-36m-aach64-linux-gnu.so apt_pkg.so
sudo pip3 cython


##共通設定：
下記パッケージをインストール。
sudo -HE apt-get install -y --no-install-recommends \
    ca-certificates \
    curl \
    g++ \
    git \
    libhdf5-dev \
    liblapack-dev \
    make \
    libssl-dev \
    portaudio19-dev \
    libffi-dev \
    python3-pip \
    python3-setuptools \
    python3-wheel \
    protobuf-compiler \ 
libprotoc-dev \
libatlas-base-dev \ 
gfortran

##cmakeの最新版インストール

wget https://github.com/Kitware/CMake/releases/download/v3.16.5/cmake-3.16.5.tar.gz
tar xvf cmake-3.16.5.tar.gz
cd cmake-3.16.5
./configure
make –j4
sudo make install


##protobufのソースからのインストール
curl -L https://github.com/google/protobuf/archive/v3.1.0.tar.gz -o protobuf-v3.1.0.tar.gz
tar xvf protobuf-v3.1.0.tar.gz
cd protobuf-3.1.0
mkdir build && cd build
cmake -DCMAKE_POSITION_INDEPENDENT_CODE=ON -Dprotobuf_BUILD_TESTS=OFF ../cmake
make –j4
sudo make install

cd ../..

sudo -HE pip3 install \
	--no-cache-dir \
	--global-option=build_ext \
	--global-option="-I/usr/include/hdf5/serial" \
	--global-option="-L/usr/lib/arm-linux-gnueabihf/hdf5/serial" \
	h5py

sudo pip3 install pybind11

##NNablaのビルド
git clone https://github.com/sony/nnabla
cd nnabla
sudo pip3 install -U -r python/setup_requirements.txt
sudo pip3 install -U -r python/requirements.txt

mkdir build
cd build
cmake ../ -DPYTHON_COMMAND_NAME=python3.7
make -j4
sudo make install

cd dist
sudo pip3 install nnabla-1.6.0.dev1-cp37-cp37m-linux_aach64.whl # バージョンとアーキテクチャはビルド結果で異なる。

上記でエラーが無ければ環境構築完了。
【今日のエラー】Routing Errorとrenderメソッド


今日まず一つ目のエラーは`Rooting Error`でした。

#Rooting Error　~ただのスペルミス編~
下記の画像のようなrooting errorに１時間くらいハマってました...

<img width="1208" alt="スクリーンショット 2020-03-16 15.41.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593736/988beb1c-e961-661b-03da-70909ff3a2f2.png">

あれ〜、ちゃんとrootでindexアクション書いたしToppagesControllerも作成したのに...

ファイル名書き間違えたかな〜、でも合ってるしう〜ん...
でもエラー的にトップページに飛べてない気がする...

ん？

<img width="405" alt="スクリーンショット 2020-03-16 15.41.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/593736/4208d672-05fa-e53c-7a2d-6e81cf7049e4.png">

__TopppagesController__って何だこれ笑

単純にコントローラーのスペルミスでした...
p一つ多いだけで１時間かかるのはまずいので、もっと正確に慎重にコード書こうと思いました。

######備忘録(renderについて)
簡単にまとめると、何度も使う部分や共通の部分についてrenderを割り振っておくことで呼び出しに使用することができる。

例えば

```app/views/index.html.erb

<p>
  main
</p>

#app/views/_headder.html.erb

<p>
  headder
</p>

#app/views/_footer.html.erb

<p>
  footer
</p>
```

これだけだとまだ読み込まれていないので

```#app/views/index.html.erb

<%= render 'headder'%>
<p>
  main
</p>
<%= render 'footer'%>
```

こうすることで、無事にindex内でfooterとheaderが読み込まれる。
あとここわかってなかったのが、__冒頭にアンダーバーをつけないとrenderで読み込まれないこと笑__
しょうもないけど何で！？ってなってたので調べてスッキリしました。


###参考文献
[Rooting Errorの質問](https://teratail.com/questions/13505)
[renderメソッドを使う方法](https://techacademy.jp/magazine/7780)
Raspberry pi,Jetson Nanoでリアルタイム音声信号への機械学習モデルによるエフェクト(nnabla学習モデルエクスポート編)

[前回](https://qiita.com/kmitsu76/items/dd23a64ac58ab327a40f)作成したbest_result.h5を組み込み機器へ転送しやすいnnpファイルへ変換する。
別のpythonプログラムで、一度best_result.h5を読み込みモデルを作成、速度計測のため一度推論を行い、最後にnnpファイルへ保存する。

```
    contents = {
        'networks': [
            {'name': 'MyChain',
            'batch_size': batch_size,
            'outputs': {'yy': yy },
            'names': {'xx': xx}}],
        'executors': [
            {'name': 'runtime',
            'network': 'MyChain',
            'data': ['xx'],
            'output': ['yy']}]}
    nnabla.utils.save.save(os.path.join('MyChain.nnp'), contents)
```

python3 predict.py -i <エフェクト前のwavファイル>

上記を実行すると、同じフォルダにpredicted.wavと、MyChain.nnpができる。
この規模の学習モデルの変換にかかった時間はおおよそ下記のとおり。

1回の推論でかかるおおよその時間：
960/480*64バッチサイズ(中間層セル数16)で1秒強かかっている。
出力として使われるデータは、480*64=30720
サンプリング周波数48khzとすると、1秒間48000サンプルということで、
本来は30720/48000=0.64秒で終わらないといけない。
		
CPUパワーのあるデスクトップPC (Core-i5 2500S)2.7Ghz　4コア（ターボブースト3.7Ghz）でこの結果なので、Raspberry pi、Jetso Nano では推論のさせ方を検討しないとリアルタイムで処理はできないことになる。

nnp作成時間：15分くらい時間がかかり、8.15MBのファイルが出来上がる。
			
※そもそもinput_timestepsから半分も捨てるのはもったいないのでは、ということで、
全部の長さを推論として使う設定、output_timesteps=960(input_timestepsと同値)にして
推論を行ったらどうなるか。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/8b9349ae-8257-c84d-92ce-a9077bbbe537.png)
推論が始まりデータが落ち着くまでの間、スパイクノイズが960サンプルで観測される。
スライディングウインドウはこのデータの収れんされていない部分を削って消してくれる働きがあることが分かった。今回の480は削りすぎかもしれないが、学習データの内容によってチューニングできる部分になるだろう。

推測だが、いろいろいじっていると、学習時にTensorboardで観測されたグラフと形状が相似している印象を持った。

下記がtensorboardのグラフ。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/387653/7c82fea8-a36d-acf5-ea0c-ce4b3bed2d69.png)
Laravelの日本語化パッケージ

# 目的

Laravelの日本語化を行い、その言語リソースをパッケージ化してみる。

# 日本語化について

[Laravel 6.x 多言語化](https://readouble.com/laravel/6.x/ja/localization.html)

## 設定

config/app.php

```php
    'locale' => 'en',
```

## 英語→日本語

デフォルトでは次の４種類が用意されている。

1. 認証（auth.php）
2. ページネーション（pagination.php）
3. パスワードリセット（passwords.php）
4. バリデーション（validation.php）

***resources/lang/en***以下に対応するphpファイルがあるので、それを翻訳して***resources/lang/ja***以下へ置く。

# パッケージ化について

毎回翻訳するのは大変なのでパッケージ化してみる。

[Laravel 6.x パッケージ開発](https://readouble.com/laravel/6.x/ja/packages.html)

***ServiceProvider***で作成した日本語化ファイルを公開できるようにする。

```php
    public function boot()
    {
        $this->publishes([
            __DIR__.'/../resources/lang' => $this->app->resourcePath('lang/'),
        ], 'lang-ja');
    }
```

***vendor:publish***コマンドで公開できるようになる。

```console
$ php artisan vendor:publish --tag=lang-ja
```

# 作成した日本語化パッケージ

[blue32a/laravel-language-ja](https://github.com/blue32a/laravel-language-ja)

ほぼGoogle翻訳なので使いつつ調整していく予定。
『アルゴリズム図鑑』のアルゴリズムをPython3で実装(選択ソート編)

#この記事について
この記事では筆者が『アルゴリズム図鑑』を読んで学んだアルゴリズムについて、Python3での実装例を紹介したいと思います。今回のアルゴリズムは選択ソートです。筆者は素人です。色々教えていただけると幸いです。

筆者はPython2のことをよく知りませんが、自分がPython3を使ってるっぽいことだけはわかっています(Python3.6.0かな？)。そのため、記事のタイトルではPython3としました。

#選択ソートについて
問題設定とアプローチについてざっくりとだけ説明します。

###問題
与えられた数の列に対して、小さい数から順に並べ替えた列を返す。
例：
　4, 3, 1, 2
→ 1, 2, 3, 4
###アプローチ
先頭から順に値を確定させる。未確定の数から最小値を見つけ、入れ替えによって前(先頭側)に持ってくる。詳細は『アルゴリズム図鑑』を参照。

例：
確定された数を[ ]で囲って表記
　4, 3, 1, 2
→ [1], 3, 4, 2
→ [1], [2], 4, 3
→ [1], [2], [3], 4

#実装コードと実行結果
実装したコードを以下に示します。最初に変数dataに代入されているリストが処理対象の数の列です。また、リストのminはあえて使わずに実装しました。

###コード
```python:selection_sort.py
data = [4, 3, 1, 2]
print("input    :" + str(data))

data_len = len(data)

for k in range(0, data_len - 1):
    min_index = k
    min_data = data[k]
    for i in range(k + 1, data_len):
        if data[i] < min_data:
            min_index = i
            min_data = data[i]
        else:
            pass
    data[min_index] = data[k]
    data[k] = min_data

print("output   :" + str(data))

```

###実行結果
```bash:
$ python selection_sort.py 
input    :[4, 3, 1, 2]
output   :[1, 2, 3, 4]
```

#終わりに
自分の書いたコードを投稿する練習も兼ねて初投稿してみました。気づいた点などあればご指摘、ご質問いただければと思います。特にコードの書き方の改善点などあれば勉強になるなと思います。
初心者のための『なんでGitでブランチを使うねん！！』を再復習しよう！

#はじめに
こんにちは！ベンチャー企業でソフトウェア開発をしている加納です！

意欲が高く一人で勉強されている初心者プログラマの方はGitの存在を知ってるかもしれません。Progateにも詳しい手順が解説されていたりしますよね！

実務経験がない状態だと（僕もそうだったのですが）『なぜGitでブランチを使うのか』と思うことがあると思います。今回はその理由を図を用いてわかりやすく解説いたします！

#この記事を読んで得られること
Gitのブランチを用いた開発の良さを知って頂ければと思います。

#本題：『なぜGitでブランチを使うのか』
結論から言いますと、『ブランチを使わない開発は危険すぎるから』です。

具体的に**ブランチを使わず開発をしている危険性**を見ていきましょう。

![ブランチ1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481370/24fddc0b-c8bc-c4d0-0e57-d7b85e38f171.png)

上の図のように本番環境だけで開発をしているとします。何が起こってしまうでしょうか。![ブランチ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481370/69986491-0312-e00b-6162-03d8a4a8d2de.png)

このように直で本番環境のコードを書き直したり、付け足したりしていると突然システムが機能しなくなってしまうこともあるのです。正直めちゃめちゃ焦ります。何を変更したんだっけと全て忘れてしまうかもしれないです（僕はそうです）

もちろんバックアップをとっておいたら良いのですが毎回コードを少し変えるたびにバックアップを取っていると無限に不要なフォルダができてしまうかもしれません。

そこで**ブランチ**を使うのです！！

#ブランチの素晴らしさ
以下がブランチを用いて作業をした時の図です。
![ブランチ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/481370/34e0f1cc-8eb6-70ec-1bcd-ac5c9e7dd1de.png)


先ほどまでは**[開発段階2]**から**[開発段階3]**を直で変更していましたが、ブランチを使うとどうでしょう。

最低でも「開発用」、「テスト用」、「本番用」ブランチを用意して開発をすることで、**[開発段階2]**のコードはそのままにして、そのクローンをこまめに開発することができるのです！

開発中にバグが発生しても問題ありません。元のブランチを参照することですぐにバグが発生する前のコードに戻れるのです。

本番用ブランチで動作を確認し終えたのなら、[開発段階2]と[本番用ブランチ]をマージして終了となります。

#最後に
最後まで読んでいただきありがとうございました。
一人で開発をしている方や、友達と開発をしている方！ぜひブランチを使って安全で快適なエンジニアライフをどうぞ！！

Gitのブランチの必要性を教えていただいた大先輩エンジニアの青木さんに感謝致します。

#関連記事
・具体的なブランチの構成について知りたい
→[いまさらだけどGitを基本から分かりやすくまとめてみた](https://qiita.com/gold-kou/items/7f6a3b46e2781b0dd4a0)

・効率的に優秀なプログラマになる方法を知りたい
→[ハッキングを学ぼう-日本語訳](http://ycdw.xyz/howtolearnhacking/)
KotlinのGenericsで継承を使う方法

runSyncで通信したAPIからのレスポンスをsaveメソッドに渡して保存処理を始めるという処理を書くのに、他でも使うからinterfaceで定義してよしなにしようとしたけど、ちょっと詰まった。
詰まったのは、saveメソッドの引数がRespons<*>の形なのでGenericsになっている。
Genericsの型は当然APIによって異なる。
よって、その部分を継承でうまいことできるようにしないといけない。
#結論
```kotlin
fun save(response: Response<out Serializable?>)
```
こんな感じになりました。

outというのがキーワードみたいで、Javaでいうextendsがこれにあたる(多分)

後ろの?を取るとエラーが出るので重要な意味っぽい(調べてない)

一応、公式リファレンスは[ここ](https://dogwood008.github.io/kotlin-web-site-ja/docs/reference/generics.html)なので、ちゃんと知りたい人はこっちを見て下さい。