OmniAICreator/Qiita-1.07M huggingface dataset:
RHEL系Linuxでc++コードをビルドする

# 前提
- g++を使用したい
- rpmbuildも使用したい
- ソースコードはGitリポジトリからダウンロードしたい

# RHEL 7.x
## g++のインストール
以下のコマンドを実行する。

```
$ sudo yum repolist all
```
"rhui-REGION-rhel-server-rhscl"がenabledになっていなければ，次のコマンドを実行する。

```
$ sudo yum-config-manager --enable rhui-REGION-rhel-server-rhscl
```
再度以下のコマンドを実行し，"rhui-REGION-rhel-server-rhscl"がenabledになっていることを確認する。

```
$ sudo yum repolist all
```
以下のコマンドでg++およびrpmbuildをインストールを実行する。

```
$ sudo yum install devtoolset-7
$ sudo yum install rpm-build
```
以下のコマンドでg++のバージョンを確認する。

```
$ scl enable devtoolset-7 bash
$ g++ --version
```

## Gitリポジトリからソースコードをダウンロード
```
git clone -q --branch=master https://github.com/xxx/xxx.git /home/ec2-user/xxx
```
クローンしたワークフォルダーに入り下記のコマンドを実行すると，最新のソースコードがダウンロードされる。

```
$ git pull origin master
```
強制的に上書きするには下記のコマンドを実行する。

```
$ git fetch origin master
$ git reset --hard origin/master
```

# AlmaLinux 8.x
## Minimal installのAlmaLinuxへのインストール

yum install gcc
yum install rpm-build
yum install git
yum install make
yum install gcc-c++
yum install openssl-devel
yum install libstdc++-static

ODBC接続でデータベースにアクセスするには、unixODBCおよびunixODBC-develのrpmをダウンロード後インストールする。
npx create-react-appでThe engine "node" is incompatible with this module.が出てしまう時

##やろうと思ったこと
`npx create-react-app xxxx`で環境構築

## 事象
`npx create-react-app xxxx`
や
`npm install -g create-react-app`([←現在は非推奨](https://facebook.github.io/create-react-app/docs/getting-started))
を叩いた時に下記エラーが出た。
とりあえず、最新のnodeやcreate-react-appを入れ直してみたものの、解消せず。
前は動いてたのになんで...!?


```
yarn add v1.15.2
[1/4] 🔍  Resolving packages...
[2/4] 🚚  Fetching packages...
error eslint@6.1.0: The engine "node" is incompatible with this module. Expected version "^8.10.0 || ^10.13.0 || >=11.10.1". Got "11.3.0"
error Found incompatible module
info Visit https://yarnpkg.com/en/docs/cli/add for documentation about this command.
```

##調査
エラー内容としてはnodeのverが不適合とのこと。


さっき最新(`v11.3.0`)にしたのにな〜、、、
という安易に考えていたのがダメでしたね(恥)


node.jsのリリースには下記のような区分があり、`v11.3.0`は2019年8月現在ではまだ推奨版であるLTS対象ではないようです。**なので最新のLTS対応Verに変更すれば良さそう?です。**

```
1.Current(最新) : 最新版Verだが、安定性には欠く
2.LTS :  Node.js projectにより長期的に保守・運用される対象となっているVer
 → 2-1. Active(推奨版) : 保守やアップグレードが積極的に行われているVer
 → 2-2. Maintenance(保守) : 最低限のサポートはされるが、もうそろそろ終わりという感じ
```

### 最新のLTS
じゃあ最新LTSであるかはどこで判断するのかというと、こちら。
https://nodejs.org/ja/download/
本記事執筆時点では`最新のバージョン: 10.16.2 (同梱 npm 6.9.0)`のようです。

また、リリース一覧も見てみましょう。
https://nodejs.org/ja/download/releases/
本記事執筆時点ではリストの一覧に`Node.js 10.16.2 Dubnium`と書いてあり、かつ最新LTSとなっています。
(Dubniumというのは最新LTSにつけられたコードネームのようですね)

### リリースのライフサイクル
ちょっと横道にそれますが、node.jsのLTSリリースには下記のサイクルがあるようです。
1. リリース後最初の半年を「Current」
2. 次の1年半を「Active」
3. その次の1年が「Maintenance」
![nodejs-lts-lifecycle_preview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146742/9095f905-ca64-3526-8a9a-5cd93f4bdd48.png)

また、リリースナンバーは法則があり、
・ 奇数バージョンは最新機能版(ex. Node.js 7, Node.js 9, Node.js 11)
・ 偶数バージョンが長期サポート版(ex. Node.js 8, Node.js 10, Node.js 12)
となっているようです。

##対応
LTSではないVerのnodeを使用しており、今回のエラーが発生したと思われるので、
node.jsのVerを変えるためにnvmをインストール

```
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
```
macの場合は.bash_profileに下記を追加

```
export NVM_DIR="${XDG_CONFIG_HOME/:-$HOME/.}nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
```
最新のLTSをインストール

```
nvm install --lts
nvm use --lts
node -v
```

これで最新LTSが入り、`npx create-react-app xxxx`が動きました。

また、別フォルダを作成してそこで`npx create-react-app xxxx`を叩こうとした時に、再度nodeがCurrent Verになっていたら上記nvmコマンドでLTSにして実行するとOKです。

##参考
・[【解決】yarn addでwebpackを追加する時にエラーが出た話](http://teinen.hatenablog.jp/entry/2018/04/26/231951)
・[Understanding How Node.js Release Lines Work](https://nodesource.com/blog/understanding-how-node-js-release-lines-work/)
・[nvm + Node.js + npmのインストール](https://qiita.com/sansaisoba/items/242a8ba95bf70ba179d3)
GeopyでGoogle MapのAPIを叩く方法

# 概要

知人に[Geopy](https://geopy.readthedocs.io/en/stable/)について聞かれて調べたときの備忘録。
いつか自分でgeocodingするときのために。
（geocodingとは、住所↔緯度経度の変換のことを指すらしい）

# Geopyのインストール

環境は[Anaconda](https://www.anaconda.com/distribution/) (windows 10)上で構築。

```bash
pip install geopy
```

# GCPのAPI Keyを取得

[Google Maps Platform](https://developers.google.com/maps/documentation/geocoding/get-api-key)からAPI Keyを取得。

# 住所から座標へ

正確な住所から座標への変換ができれば十分だけど、Google mapと同じように、適当な文字列からいい感じの検索結果を出してくれることを期待。。。

```Python
from geopy.geocoders import GoogleV3
g = GoogleV3(API_KEY) 
g.geocode('白旗の湯', timeout=10)
Location(112-1 Kusatsu, Agatsuma District, Gunma 377-1711, Japan, (36.6225756, 138.5962787, 0.0))
```

Google Mapで群馬県吾妻郡草津町112-1を確認してみる。
無事、白旗の湯に辿り着きました。すごい。

<img width="960" alt="kusatsu.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/127680/edf4c9a2-ce29-884a-921f-3c1a4dd98cca.png">

フル住所でも一応確認。

```Python
g.geocode('群馬県吾妻郡草津町112-1', timeout=10)
Location(112-1 Kusatsu, Agatsuma District, Gunma 377-1711, Japan, (36.622506, 138.596808, 0.0))
```

# 座標から住所へ

逆方向もついでに。

```Python
g.reverse((36.6225756, 138.5962787, 0.0), timeout=10)
[Location(112-1 Kusatsu, Agatsuma District, Gunma 377-1711, Japan, (36.6225756, 138.5962787, 0.0)),
 Location(419 Kusatsu, Agatsuma-gun, Gunma 377-1711, Japan, (36.6226335, 138.5961949, 0.0)),
 Location(Yutaki Street, Kusatsu, Agatsuma-gun, Gunma 377-1711, Japan, (36.6224974, 138.596249, 0.0)),
 Location(377-1711, Japan, (36.6271446, 138.5887875, 0.0)),
 Location(Kusatsu, Agatsuma District, Gunma 377-1711, Japan, (36.6271446, 138.5887875, 0.0)),
 Location(Kusatsu, Agatsuma District, Gunma, Japan, (36.6207181, 138.5960945, 0.0)),
 Location(Agatsuma District, Gunma, Japan, (36.5314431, 138.6388879, 0.0)),
 Location(Gunma, Japan, (36.5605388, 138.8799972, 0.0)),
 Location(Honshu, Japan, (36.16999990000001, 138.04, 0.0)),
 Location(Japan, (36.204824, 138.252924, 0.0))]
```

ちゃんと白旗の湯に行けている。
行きたいなあ。。。
キレイなコードを書くための備忘録

#概要
[「Clean Code アジャイルソフトウェア達人の技」](https://www.amazon.co.jp/Clean-Code-%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%81%94%E4%BA%BA%E3%81%AE%E6%8A%80-Robert-C-Martin/dp/4048930591)を読み、コードをキレイにするために重要だと感じたルールを簡単にまとめました。他の人が自分のコードを読みやすくするため、拡張性、保守性の高いコードにするために重要なものだと思います。

##関数
1. **メソッドはなるべく小さく(3,4行)**
一つのメソッドで1つの役割。複数のプロセスを含む場合は分解する。

2. **インデントは1つか2つまで**
if文やfor文でのネスティングは少なめにする。

3. **メソッド内の抽象度レベルを揃える。**
4. **わかりやすいメソッド名。**
初めてコードを読む人でも何を表しているかわかるように。

5. **引数は少なく。0が理想、2つ以下。**
booleanは引数にしない。booleanを引数として渡しているのは、中で条件分岐しているということ。

6. **副作用をなくす。(隠れたプロセス)**
メソッド名などからはわからない、隠れた処理はなくす。

7. **関数の呼び出し元を見なくてもわかるようにする。**
メソッド名で何をしているかわかるように。

8. **try catchの中身はメソッドに切り出す。**
try, catchを使うと、どうしても見づらくなるため。

9. **DRY(Don't repeat yourself)原則。**
同じコードを繰り返さない。

10. **条件式のカプセル化。できるだけ肯定形で。**
!やnot◯◯はできるだけ使わない。

##書式化
1. **変数、privateメソッドは使う場所の近くに書く。**
縦方向に大きくスクロールする必要がなくなり、見やすい。

2. **説明的変数を使う。**
計算過程の値に変数名をつける。

3. **境界条件のカプセル化**
条件式などで使われる境界値を変数名として抽出する。

4. **メソッドは抽象度レベル順に並べる。**

5. **コメントはできるだけ使わない。**
メソッド名、変数名、クラス名でわかるようにする。

##オブジェクトとデータ構造
手続き型は後から関数を追加しやすい。オブジェクト指向はクラスを追加しやすい。

1. **デメテルの法則**<br>
オブジェクトを使用する際、そのオブジェクトの内部について知るべきではない。クラスの依存関係を減らす。

##例外処理
1. **非チェック例外を使う。**
2. **エラーコードではなく例外クラスを返す。**
3. **catchしたところで、十分なログを書く。**
4. **nullを返さない。**
nullチェックが多くなりがち。空リストなどにして返すことで対処する。

5. **nullを引数として渡さない。**
nullが渡されたときに上手く対処できるメソッドは少ない。nullを渡すことは原則禁止にした方が良い。

##境界
1. **外部連携が必要な際、まだ存在しないコードはインターフェースを使う。**

##テストコード
何をテストしているかわかりやすくする。
1. **1つのテストに1つのassert。**
2. **1つのテストで1つの概念。**

##クラス
1. **変数はprivateにする**
2. **SRP(single responsibility principle)**
1つのクラスに1つの役割。


##単純な設計のための4つの規則
上から順に優先順位が高い。(②と③は同じぐらい)
①**Passes the tests(テストが通ること)**
テストが通ること。意図した通りにコードが動作することを常に検証できる。

②**Reveals intention(意図が明快であること)**
良い命名、関数とクラスを小さく保つこと、デザインのパターンの適用などにより、書き手の意図を明快にする。

③**No duplication(重複の排除)**

④**Fewest elements(クラスとメソッドを最小限に)**
関数とクラスの数を少なくする。

#まとめ
　コメントを使わず、コードを読めば何をしているかわかるようにするのが理想だと思います。変数名、メソッド名、クラスの分け方などを工夫し、個人的には**自然言語を読むのと同じように読めるコード**を書けるようにしたい感じました。
　また、テストがあれば思い切って、リファクタリングできます。いつでもコードをキレイにできるよう、TDDなどを駆使して、テストは常に十分に書いておきたいです。実際にはコードをキレイにする時間をなかなか取れないことが多いですが、「ボーイスカウトの規則」を意識して、**自分が見つけたコードは、見つけた時よりもキレイに**して、汚いコードを減らしていこうと思います。

###参考文献
 1. [Clean Code アジャイルソフトウェア達人の技](https://www.amazon.co.jp/Clean-Code-%E3%82%A2%E3%82%B8%E3%83%A3%E3%82%A4%E3%83%AB%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2%E9%81%94%E4%BA%BA%E3%81%AE%E6%8A%80-Robert-C-Martin/dp/4048930591)
 2. [BeckDesignRules](https://martinfowler.com/bliki/BeckDesignRules.html)
ただの日記


#神嶌敏弘さんのPDFにて
機械学習やデータマイニングのスペシャリストである神嶌敏弘さんが[クラスタリング](http://www.kamishima.net/archive/clustering.pdf) で言っていたことで、このような文章があります。
>クラスタリングは探索的(exploratory)な解析手法で，分類結果はある主観や視点に基づいている．よって，結果は，データの要約などの知見を得るために用い，客観的な証拠として用いてはならない

私の解釈では、「クラスタリングのグループ分けが絶対正しい！ということではないよ」ということを言っているのかなと思いました。クラスタリングは、あくまでも考えの一つとしてとらえるのが正しいのかもしれません。
Webを支える技術の備忘録

# Web
●技術としてのWeb
Web
 - HTML
 - URI
 - HTTP
で構成される。
これらは相互に関係している。

API(JSON, XML)：プログラム向け
HTML：ユーザ向け


●システムとしてのWeb
Web
 - ハイパーメディア（テキストやイメージをリンクでつなげるシステム）
 - 分散システム（複数のPCに処理を分散するシステム）
で構成される。


TCP/IP→リアルタイム通信

ハイパーテキスト：テキストのみをリンクでつなげるシステム
ハイパーメディア：テキストだけでなく、画像や音声などもリンクでつなげるシステム

# REST
HTTP
HyperTextをTransferするProtocolだが、実際にはハイパーテキストに限らず画像や音声など
様々な情報（Representational State)をTransferしている
→REST(REpresentational State Transfer)

RESTはアーキテクチャスタイル
Client/Serverに制限をつけていったものがREST

アーキテクチャスタイル（REST)
↑
アーキテクチャ（Web）
↑
実装（Firefox,Apache...）

Client/Server
　∋ REST
　　∋ Web
　　　∋ Firefox, Apache...

# リソース
Web上に存在する情報のこと
唯一無二のものであり、表現方法は違えど(ex. todayと20190831)
唯一無二を確実にするような命名が必要
→URIを使用

# URI、URL、URN

URI
Uniform Resource IDentifierの略
リソースを識別するIDのこと

URL：Uniform Resource Locator
URN：Uniform Resource Name → isbnなど（書籍のアレ）

URIが変わらないような設計が必要（URLに言語仕様とかメソッド名とかセッションIDとかいれない）
Python勉強の記録_190812

#やったこと
- AtCoder昨日の続き（[AtCoder に登録したら次にやること ～ これだけ解けば十分闘える！過去問精選 10 問 ～](https://qiita.com/KoyanagiHitoshi/items/c5e82841b8d0f750851d)）の残りを解いた

#学び
- リストの昇順・降順並び替え（昇順にしてからじゃないと降順にできないのでしょうか）

```python
lst = [1, 7, 5]
lst.sort()
print(lst)
#[1, 5, 7] <--昇順
lst.reverse()
print(lst)
#[7, 5, 1] <--降順
```

- set型（集合。重複しないリスト）の扱い方

```python
#set型オブジェクト作成
set1 = set([1, 1, 2, 3])
print(set1)
#{1, 3, 2}

#要素の追加
set1.add(5)
print(set1)
#{1, 2, 3, 5}
```

- プログラムを終了
（`import sys`しないでも通った）

```python
exit()
```

- 文字列の置換

```python
l = "letter"
l2 = l.replace('t', 'T')
print(l2)
#"leTTer"
```
cd desktopでエラーに詰まった件について

windows10を使ってCLI操作をしている人に向けて書いています。


最近vue CLIでの環境構築を学び、CLI操作をよくつかうようになった。
そこでよく使われる「cd desktop」を入力するとエラーに襲われた。
根気よくググっていくと、**デスクトップには初期でonedriveが同期されているらしく**、それを止めれば、『cd desktop』のエラーが解消されるとのことだった。

#C:\Users\"ユーザー名"/OneDrive\デスクトップ　の状態から Onedriveを取り除く方法を解説する

1　タスクバーからonedriveを選択
![スクリーンショット (6).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/fa96c0e8-45e4-977b-5f94-b8f2d6d69790.png)
「その他」をクリック

２![スクリーンショット (7).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/81eb90c2-a89f-2308-2d58-14d9d82d2d1f.png)
「設定」をクリックして・・・・

３　「バックアップ」をクリックし、
さらに「バックアップを管理」をクリック![スクリーンショット (8).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/3e57989c-d28f-fd57-3e4f-23bae713ab9a.png)

４![スクリーンショット (9).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/000905c1-ed3b-d5a2-ef4b-9d143b4ed679.png)

から「デスクトップ」、「写真」、「ドキュメント」から「バックアップを停止」をクリック
![スクリーンショット (10).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/2e0c205f-786a-6ee0-5991-6920a09afbda.png)

**これで、#C:\Users\"ユーザー名"/OneDrive\デスクトップ　の状態から Onedriveを取り除けました！**

![スクリーンショット (11).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439295/b01c6d35-d492-b37c-a1bc-2d62bf3da838.png)

こんな落とし穴があったなんて、自分はこれを解決するのに半日以上費やしてしまいました。金が溜まれば、さっさとmacbookに乗り換えようと思います。

参考URL
[OneDriveフォルダを削除する方法](https://answers.microsoft.com/ja-jp/windows/forum/all/onedrive%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80/9b92ae0c-dab3-46ca-b61a-04f41c1c9f30)
Google Bigqueryでのテーブル作成方法(CSVインポート）※2022/2改訂版

CSVファイルをbigqueryにインポートする手順のメモ

## やりたい事
・CSVファイルをbigqueryに単純インポートする
※項目名やtypeを変更したい場合は、[こちら](https://qiita.com/ymto/items/8cc10cc198bb71ef792d "Google Bigqueryでのテーブル作成方法(CSVインポート/カラムのtypeを変更したい場合）")

#####1. bigqueryのコンソールからテーブルを作成したいプロジェクトとデータセットを選択して、設定から「Create table」を選択する。 
![bigqueryへのCSVアップロード1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/26d2ef04-6ed8-2e99-daec-ebaf4a912daa.png)


#####2. テーブル作成用コンソールが出現する為、アップロードしたいCSVファイルを選択し、bigquery上に作成するテーブル名を指定して「CREATE TABLE」を指定する 
![bigqueryへのCSVアップロード2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/22aef8d2-c4f9-4478-df10-410243868175.png)
![bigqueryへのCSVアップロード3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/2aa0215e-b0b2-6be8-6951-08b089fd380a.png)


#####3. エラーが出なければ、テーブルが作成されて取り込まれたのがわかる
![bigqueryへのCSVアップロード4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/242038/b783127e-bb92-e6fb-a39b-3c032cc5477f.png)



##注意点
取込対象のCSVファイルの文字コードは必ず **UTF-8** にしておく必要がある。
→これを怠るとエラーになったり、取り込んだ文字が文字化けして使い物にならなくなる事が多い。

CSVのヘッダーはローマ字にしておく
→取り込んだテーブルのカラムになるため、ローマ字以外だと文字化けして意味不明になる。

[文字コード変換方法はここら辺を参考に](https://uxmilk.jp/47955)
エクセルマクロ(Excel VBA)で株式指標（RSI）を計算する

# エクセルマクロ(Excel VBA)で株式指標（RSI）を計算する
## 本記事について
4本値データから、RSIを計算する。テクニカルトレーダーなら一度はやったことがあると思います。しかしこの計算、文字で書くのは簡単ですが

+ 前日との差を求める
+ 全日差のうちプラスの値のみ足し合わせる
+ 全日差のうち、マイナスの値のみ足し合わせる
+ プラスの和　/ ( プラスの和＋マイナスの和　) × 100 を計算する

これらの計算は一発ではできず、途中式をエクセル上に残しておかなければなりません。
非表示セルにしてもよいですが、後から見返したときに大量の「中間式」があると分かりにくい・・・
本記事では、そういった「面倒な部分」を全てマクロ（VBA）にお任せして、エクセルシートを簡潔にすることを目的とします。

## マクロを使用した場合と使用しない場合の比較
### マクロを使用しない場合（エクセル関数のみ）
全日差を求めた後、SUMIFS関数を用いてプラスのみ、マイナスのみの合計を求めてからRSIを計算しています。
RSIを求めたいだけなのに、途中式のための行が3行も増えてしまいました。
後から見返したら、何をしているのか分からなくなる原因です。
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223372/3d30d5eb-ee57-cc3e-9851-762789051229.png)

### マクロを使用した場合
マクロを使用した場合、以下の一行でRSIを求めることができます
`=RSI(先頭セル, RSIの日数)`
今回紹介するコードは、下図のように昇順でデータを並べ、最新のデータを先頭セルとして選択すれば、下方向にデータを引っ張ってくる仕様になっています。
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223372/9e8b5dbb-fe16-2d1c-afaf-8c64de4b7a7f.png)

##ソースコード

```vb:RSI.bas
' RSIを計算する
' arg RSIを求める先頭セル（先頭セルから下方向に計算する)
' day RSIの日数
Function RSI(先頭セル As Range, RSIの日数 As Long) As Double

    ' 計算対象セルを保存する
    Dim calcCell As Range
    ' プラスの差分の和
    Dim plusSum As Long
    plusSum = 0
    ' プラスマイナスの差分の和
    Dim allSum As Long
    allSum = 0
    ' 差分を保存する
    Dim delta As Long
    delta = 0
    
    Dim i As Long
    For i = 0 To RSIの日数 - 1
        ' 計算対象セルを日数分ずらしていく
        Set calcCell = Cells(先頭セル(1).Row + i, 先頭セル(1).Column)
        
        ' 該当足のデータが数値以外・空白のセルの場合エラー
        If (Not IsNumeric(calcCell)) Or IsEmpty(calcCell) Then
            RSI = CVErr(xlErrNA)
            Exit Function
        End If
        
        ' 一本前のデータが数値以外・空白のセルの場合エラー
        If (Not IsNumeric(calcCell.Offset(1))) Or IsEmpty(calcCell.Offset(1)) Then
            RSI = CVErr(xlErrNA)
            Exit Function
        End If
        
        ' 一本前の値との差を求める
        delta = calcCell.Value - calcCell.Offset(1).Value
        
        ' プラスの場合、差分を追加
        If 0 < delta Then
            plusSum = plusSum + delta
        End If
        
        ' プラマイ関係なく、差分の絶対値を追加
        allSum = allSum + Math.Abs(delta)
    Next
    
    ' RSIを計算する
    RSI = plusSum / allSum * 100

End Function
```
Vueを学び始めて２週間でルーレットアプリを公開した

#はじめに
今回

[MRoulette](https://masibw.github.io/MRoulette/)


というルーレットアプリを開発、公開したのでそれについて色々書いてみたいと思います。
（名前は~~安直に~~MasiRouletteから）

コードは  [こちら](https://github.com/masibw/MRoulette)

##なぜルーレットアプリを作ったか
以前ルーレットで抽選をしたいと思った際に検索をしたところ意外にもwebで使えるルーレットがなかったからです（検索不足じゃなければ多分）

自分が思いつくものは大体存在しているこの時代にルーレットがなく驚いたので、じゃあ自分で作ろうと思いました

どうやってルーレットを実装しようかと思ったときに

https://qiita.com/mitsudaman/items/b30b5e905ff348bf35bc

こちらの記事の内容がほぼルーレットじゃん（）と思いすごく参考にさせてもらいました、ありがとうございます

##ルーレットのメリットとは
「今日の晩御飯どうしよう・・」や「今日は何色の服を着よう・・・」など人生は選択の連続です（）
そんなあなたの負担を減らすためにをルーレットにぱぱっと決めちゃってもらいましょう

##使った技術

- Vue.js
    - テンプレートとかDOM操作とかを良い感じにしてくれる最近流行りのやつ
- Nuxt.js
    - 同じく最近流行ってるやつ Vue.jsのフレームワークでSPAとかSSRとか良い感じにしてくれるらしい
- Chart.js
    - JavaScriptを使って円とか棒とかのグラフをすごく簡単に作ってくれるやつ
- vue-chartjs
      - 上記Chart.jsをVue.jsで使えるようにしてくれるもの
- chartjs-plugin-labels
    - Chart.jsで作ったグラフの中にラベルを表示してくれる良いやつ

##ルーレットの説明
最初こんな感じなので

<img width="1680" alt="スクリーンショット 2019-08-12 17.06.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379424/ed9d1a67-89ba-e6ee-3ccd-8015015c8422.png">

データをセットして

<img width="1680" alt="スクリーンショット 2019-08-12 17.06.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379424/50386c8b-80e1-2bca-a780-4d977d240bc8.png">

スタートを押すと

<img width="1680" alt="スクリーンショット 2019-08-12 17.07.12.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379424/30145365-2bff-2681-b1cf-1659093304c8.png">

ぐるぐる回って結果が表示されます

<img width="1680" alt="スクリーンショット 2019-08-12 17.07.25.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379424/e860f766-5afe-abae-98e2-3a4245a72424.png">


かなりシンプルに作れてよかったんじゃないかなと思います。

##工夫した部分

- シンプルかつオシャンティにしたかった
 - 割とできたんじゃないかと個人的には思う 
- 色はランダムに設定される
- 比率設定もできる
- pinの演出もPhotoShop使って自作
- 結果表示をModalWindowで行なった


##詰まったところ
- gitHub pagesにnuxt projectを上げる際に nojekyll ファイルを作成しないと _始まりのファイルが 404になってしまう
    - なぜか作成しても 空白が２行入っておりそれで反応してなかったところも詰まった
- ぐるぐる回す方法がなかなか見つからなかった
    - 最初 scssの変数で回そうと思ったけどうまくいかず js側で  pieChart.style.transform = "rotate(" + angle + "deg)";　と記述してループ
- setTimeoutやsetIntervalの中では thisによって data()内の変数にアクセスできなかった
    - const me = this にして me.変数にするとアクセスできる

##うまくいってない部分
 - ルーレットをゆっくり停止させたかったけどやりかたがわからなかった
    - そのうちなんとかしたい
 - 項目削除を最後からじゃなくてそれぞれで行いたい
    - 多分できると思うのでそのうち・・・
 -  og設定がうまく言ってない気がする・・・？
    -  もうちょっとNuxtに関する勉強しないと・・
 - ほんとはルーレット部分を録画して証拠を作れるようにしようと思ったんですが getUserMedia()の使い勝手があまり良くなく、操作やこのアプリ自体のシンプルさも損なわれそうだったのでやめました・・

##感想
今回 Vue.jsをインストールして2週間で作成・公開したというタイトルからわかるように全くのVue素人でも非常に理解しやすいフレームワークなのにとても便利で、流行ってるしフレームワークを触ってみたいという軽い気持ちからVue.jsやNuxt.jsを触り始めましたがやっぱりすごく良いですね

特にnuxt-linkやv-showには感動しました

前までは別言語の入門書を読んで勉強してましたが個人開発で色々やってみることで楽しいですし何か完成すると力がついた気がしてとても良い感じです

あと、慣れてる人からするとまだまだ汚いコードだと思いますので こうした方がいいよ　とかもあれば是非ご教授ください

##終わりに

個人的にはJavaを触りたい->SpringでWebアプリつくるか->フロントエンド勉強しなきゃ・・

という流れで進んできて、なんだかんだフロントエンドの方が勉強進んでる気がするのでそろそろjavaで何かをしたいところ・・・

こんなの良い勉強になるよ！とかあれば是非教えてください！

とりあえずは競技プログラミング等に積極的に参加してアルゴリズムやコーディング力を上げていきたいと思います。

是非皆さんも [MRoulette](https://masibw.github.io/MRoulette/) を使って 決定を楽に行なっちゃってください！
django2.2ではPyMySQL使用できず、djangoのバージョン変更する必要あり

django、python初学者です。

djangoのチュートリアルを見ながら、進めてそれぞれのファイルの使い方等を勉強しながら進めていたのですが、データベース設定の場所でつまずきました。

チュートリアル通りにデータベースの設定をしたのですが、うまく適用することができず結構時間がかかりました。

結果：Djangoのバージョンが2.2はPyMySqlに対応していないのでDjangoのバージョンを下げる必要がある。

っていうだけでした!

行った対応

- Djangoのバージョンを2.1に変更
- `pip install cryptography` で cryptographyをインストール



---



参考にしたサイト：
https://sleepless-se.net/2019/04/15/django-2-2-no-support-pymysql/
今日のbrew error: Error: Permission denied @ unlink_internal

今日のbrew error

# 1.Permission denied @ unlink_internal

```shell-session:macOS
$ brew cleanup
Warning: Skipping ansible-lint: most recent version 4.1.0 not installed

Warning: Skipping wget: most recent version 1.20.3_1 not installed
Warning: Skipping wireshark: most recent version 3.0.3 not installed
Warning: Skipping xz: most recent version 5.2.4 not installed
Warning: Skipping zsh: most recent version 5.7.1 not installed
Removing: /Users/ogawakiyoshi/Library/Caches/Homebrew/linkage.json... (1.4KB)
Removing: /Users/ogawakiyoshi/Library/Caches/Homebrew/Cask/chromedriver--2.46.zip... (6.7MB)
Removing: /Users/ogawakiyoshi/Library/Logs/Homebrew/selenium-server-standalone... (122B)
Removing: /Users/ogawakiyoshi/Library/Logs/Homebrew/iperf... (64B)
Error: Permission denied @ unlink_internal - /usr/local/share/ghostscript/9.21/Resource/CIDFSubst/Baoli.ttc
```

#2 Error: Invalid formula: 

```shell-session:macOS
$ brew install caskformula/caskformula/inkscape
==> Tapping caskformula/caskformula
Cloning into '/usr/local/Homebrew/Library/Taps/caskformula/homebrew-caskformula'...
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (4/4), done.
remote: Total 5 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (5/5), done.
Error: Invalid formula: /usr/local/Homebrew/Library/Taps/caskformula/homebrew-caskformula/Formula/inkscape.rb
inkscape: "cxx11" is not a recognized standard
Error: Cannot tap caskformula/caskformula: invalid syntax in tap!
OgawaKiyoshi-no-MacBook-Pro:~ ogawakiyoshi$ brew install inkscape
Error: No available formula with the name "inkscape" 
Found a cask named "inkscape" instead. Try
  brew cask install inkscape
```
#3 unavailable: No Cask with this name exists.

```shell-session:macOS
$ brew cask install inkspace
Error: Cask 'inkspace' is unavailable: No Cask with this name exists. Did you mean “wacom-inkspace”?
```
【Python】文字コードについてまとめる

#はじめに
Pythonの文字コードを扱うときに毎回調べてしまっているので忘れないようにざっくりまとめる。

#基本的な単語
まずは基本的な単語の意味を押さえておく。

###文字集合
名前の通り、数字や英字などの文字を集めたもの。
###文字コード
文字集合に対して数値を割り当てたもの。
コンピューターさんは数値しか認識できないので、**文字集合は全て数値で表す**。その割り当てられた数値を文字コードという。
例：大文字のAは65という数値で表される。この65が文字コード。
###エンコード
文字と文字コードを変換させるためのルール。
「この文字はこの数値で表すよ」というルール。
###ASCIIエンコード
*Amarican Standarde Code for Information Interchange*を略したもの。
コンピューターでもっとも利用されるエンコード方式。１２８種類の文字に対する数字が決められている。
２進数７ビットで表現される。
###ISO 8859
ASCIIが持っていない文字を追加したエンコード方式。
２進数８ビットで表現される。(256種類の文字を扱える。)
**Latin-1**とも呼ばれる。
###マルチバイト文字
1文字を複数のバイトで表現する。
ASCIIやISOは1文字1バイトで表現しているが、日本語や韓国語等は256種類以上の文字を扱うため、扱える文字数を増やすためにマルチバイト文字で表現する。
###ユニコード
全ての国の言語で共通して利用できるエンコード方式。
主な言語で使用される文字を集め、1つ1つにユニコード番号という番号を割り当てて基準化したもの。
UTF-8は、ユニコードで扱う文字集合をコンピュータで扱うときに利用されるエンコード方式。
###バイト型
ユニコードからエンコード変換された文字列を**Python3で扱う際の文字列オブジェクト**。
バイト型の文字列は、 `b'~'`というリテラルでも定義できる。

#文字コード変換のメソッド
##encode()メソッド
文字列オブジェクトをバイト型に変換する。引数には。変換したいエンコードを指定する。

```Python:使い方
encode(エンコード名, エラー処理の方法)
```
※エラー処理の方法については後述

##decode()メソッド
バイト型の文字列を文字列型に変換する。

```Python:使い方
decode(エンコード名, エラー処理の方法)
```
※エラー処理の方法については後述

##エラー処理の方法
文字コードの変換を行う際に使用するエラー処理の方法は以下。
####strict
エラーの際、例外のエラーを出して変換を停止する。エラー処理の方法を指定しないデフォルトの方法はこちらが採用される。
####replace
変換できない文字列があると、 `?`などの文字に置換して返し、変換を継続する。
####ignore
変換できない文字列があると、その文字列は除外され、変換を継続する。

#スクリプトファイルのエンコード指定
Pythonには、スクリプトファイルのエンコードを指定する機能があり、
Python2までは**コメントや文字列に日本語を使用する場合必ず**エンコードを指定する必要がある。
Python3以降は、**UTF-8がデフォルト**で採用されている。

スクリプトファイルのエンコードを指定する場合
 `# coding:エンコード名`
または
`# coding=エンコード名`
を記述する。なお、 `coding`の文字列前後には、以下のように任意の文字列を記述できる。
`# -*- coding:エンコード名 -*-`


#文字化け
Pythonで日本語を扱う際、文字化け問題が起こりやすい。これは、正しいエンコード方法を指定できていない場合に起きる。
日本語では、文字集合を数値に置き換えるエンコードが複数あり、文字集合が同じ場合でもエンコードが異なると、異なる数字が割り当てられ違う文字に変換されることがある。この現象を**文字化け**という。
文字化けが起きる場合、エンコードの設定が正しいかどうかを確認する。

#参考文献
[みんなのPython 第4版](https://www.amazon.co.jp/%E3%81%BF%E3%82%93%E3%81%AA%E3%81%AEPython-%E7%AC%AC4%E7%89%88-%E6%9F%B4%E7%94%B0-%E6%B7%B3-ebook/dp/B01NCOIC2P)
単体テストの勘所

##単体テスト　勘所
####〇はじめに
まず個人的な経験なのですが、下記に近い依頼の受け方をしたことがあります。
**「A,B,Cの3つの関数を単体テストして欲しいんだけど、C0/C1でカバレッジ100%で頼むよ。ツールはWinAMSで宜しく。それと100%いかなかった場合は理由の記載もお願い。」**
こういったときに「(~~こいつ~~この殿方は何言ってんの・・？)」
と思うわけです。(基本情報すら持っていないレベルで仕事してすみません)
当然いつものように罵声を浴びせられながらの聞き込みを終え、完了はできたのですが・・。
さすがに毎回この程度の質問をするのは周りに申し訳ないなー(ホントだよ？)と思いつつ、「単体テスト？何それ？」な初学者に向けてこのような惨劇は繰り返してはならん！という記事です。

####〇記事の内容
・そもそも単体テストとは
・カバレッジとは
・テスト自動化ツールとは
・スタブとは
・テストケース作成の定石

####〇単体テストとは
(一般的に)1つの関数を対象に、コーディングミスを発見するためのテスト。
実施観点としては、ブラックボックステストとホワイトボックステストに分けられる。
ブラックボックステスト・・INPUT、OUTPUTが所望の値となっているか(仕様ベーステスト)
ホワイトボックステスト・・ロジックや型のサイズ、処理の順番など間違っていないか(構造ベーステスト)
####〇カバレッジ(コードカバレッジ)とは
簡単に言うと**「所定の網羅条件がテストによってどれだけ実行されたかを割合(%)で表したもの」**という理解で差し支えないと思います。

<補足(長いからとばしてもいいよ)>
限られた工数の中で、開発しているソフトウェアのコードに対し、
信頼性や品質を確保するためのテストを実施するには「どの程度テストを実施したか」を表す指標が必要になりました。このテスト実施具合の指標を数値化して表したものをコードカバレッジと言います。 
コードカバレッジを測定することで、テストによって対象のプログラムコードがどれだけ実行されたかを判定し、テストの実施率を評価することが可能になります。また同時に、テストが実施されていない命令文や分岐文を確認することができるため、未検証のコードや不用なコード、及び不足しているテストデータを早期に発見し、品質向上につながるテストを実施することが可能になります。 
テストを実施するにあたって、カバレッジ (網羅率)を測定／分析することは、
ソフトウェアの品質向上に非常に大きな意味を持ちます。
なぜなら、カバレッジ情報からテストそのもの品質を定量的に測ることができるからです。
テストのカバレッジを測定する方法は、コードや仕様、要件、設計など、
さまざまな側面から計測する方法がありますが、単体テストの段階では、
コードベースのカバレッジでテストの品質を測ることが一般的です。
コードカバレッジを測定し、テストが実施されていないコードを確認することにより、テストの妥当性を向上させることができます。

####〇C0/命令網羅/ステートメントカバレッジ
【指針】全ての実行文を１度実行すればOK
→if文のelse側に処理がなければ、else側の判定は実施しない。

【保証できる内容】
・コーディングしたが実行されない実行文はない
・存在してはいけない実行文はない

####〇C1/判断文カバレッジ/判定条件網羅/ブランチカバレッジ
【指針】全ての条件文の真/偽を実行すればOK
→if文のelse側に処理がなくても、else側の判定は実施する。

【保証できる内容】
・存在してはいけない実行パスは存在しない

####〇C2/単純条件カバレッジ/コンディションカバレッジ
【指針】全ての条件文の条件式の組み合わせを１度実行すればOK
【保証できる内容】
・存在してはいけない条件判定式の要素がないこと

例)条件式（X and Y） or Z
→全ての条件文の条件式の組み合わせを実行

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/655d82cb-bb3e-4e8c-0e87-774feda754b3.png)

→条件要素に対する網羅性は100%だが、効果のないテストが含まれてしまう!

####〇MC/DC：Modified Condition/Decision カバレッジ
【指針】全ての条件文の条件式の組み合わせのうち、意味のある組み合わせを全て１度実行すればOK
【保証できる内容】
・C2と同等の網羅内容（テストデータはC2より少ない）

他の条件式の真偽を固定して、１つの条件式の真偽を変化させたとき、
全体の条件に変化があるものだけを実行する**「下表Yのみ実行対象となるように」**
Ｃ２の網羅性を維持して、テストパターン数を抑えることができる 

![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/450697/5dfeed2b-3a33-85d3-0f01-26d7b259093c.png)

<補足>
Yのテストケースを左から順に①②③④とすると、
①と②でZを評価
①と④でXを評価
③と④でYを評価

####〇その他カバレッジ
行カバレッジ ・ ブロックカバレッジ ・ パスカバレッジ ・ 関数カバレッジ ・ コールカバレッジ 
→とりあえずは、こういうのがあるんだなーくらいで。

####〇単体テスト自動化ツール
WinAMS・・組込みソフト単体テスト、カバレッジ計測ツールのデファクトスタンダード。
機能安全規格ISO26262(ISO:国際標準化機構) / IEC61508(IEC:国際電気標準会議)に準拠。

####〇スタブ作成の考え方
`funcA{
      A＝funcB();
　　　if(A!=0){
　　　　　　処理1
　　　}else{
　　　　　　処理2
　　　}
}`
funcAが対象のテスト。
funcBはきっと他のところでテストされているはずだし、
その正しさまで検証するのは funcA の責務ではない！！
なので、今はfuncAの正しさだけに注目すべき！
そのために funcB_stubとしてテストのために決まりきった
「正しい」挙動をするオブジェクトを注入します。
すると、テスト内でfuncB_stubは正しい動きをするとわかっているわけなので、
もしテストが失敗したとしたら「他のどこか」ではなくfuncAの実装に問題があるとわかるわけです。このように、テストを書くときは他のオブジェクトの実装に依存しないテストを作るべきです。
このために作成するのが「スタブ」です。
funcB_stubでの戻り値を固定で「0」とそれ以外の値「3」などを
設定することC1の条件が満たせる。（スタブはツールで作れるのでここでは概念だけです）

####〇さいごに
いくつか例題で考え方を示せたら分かりやすいのかな・・
改善点あればご意見おねしゃす！
カラムの型をreferences型でマイグレーションする方法

マイグレーションファイルの作成コマンド

Addカラム名テーブル名(複数形) カラム名:カラムの型
それぞれの頭文字は、大文字表示で書く。
例えばこのような書き方

```
$ rails g migration AddSalerRefToOrders saler:references
```

カラムの型をreferences型でマイグレーションする書き方は、以下のようになる。

```rb
class AddSalerRefToOrders < ActiveRecord::Migration[5.2]
  def change
    add_column :orders, :saler, :references, foreign_key: true
  end
end
```
add_columnの引数は4つあり、1つ目にカラムを追加するテーブル、2つ目に追加するカラム名、3つ目にカラムの型を指定する。また、オプションであるforeign_key: trueに部分は、任意の記載となる。

add_column :テーブル名(複数形), :カラム名, :カラムの型, オプション



＜参考記事＞
・https://kossy-web-engineer.hatenablog.com/entry/2018/09/03/022121
・https://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/remove_column
macOSでX Windows

MacintoshでWiresharkがX11版しかなかったころは、
X11をよく利用していた。

その次によく利用していたのがGIMPである。

最近、めっきりX11を利用しなくなった。

#XQuarts
https://www.xquartz.org

Mac 用の X11 について
https://support.apple.com/ja-jp/HT201341

macOSでのX Window利用
https://itcweb.cc.affrc.go.jp/affrit/documents/guide/x-window/x-win-mac



ダウンロードして解凍してもアプリケーションにアプリが現れない。
Utilitiesの中に入っていた。

#brew cask install 

```shell-session:macOS
$ brew cask install quartz
```




#参考資料
macOS MojaveでX Window System(XQuartz)を導入する
https://qiita.com/matyapiro31/items/49c16c9f5cb7fc1087d9

教授でもできるMacOSXへのX11のインストレーション
http://osksn2.hep.sci.osaka-u.ac.jp/~taku/osx/install_x11.html


MacOS Sierra上でMikuinstallerを使ってVocaloid2を動かしてみた
https://qiita.com/yohase/items/aa23a152f32bbb5b42c3

X11Forwardingがうまくいかない場合の対処
https://qiita.com/yabeenico/items/61ff3e64ee95e8d9156d

OS X 11.11 El Capitanでターミナル環境を整える (Homebrew+zsh+tmux+vim)
https://qiita.com/ysaotome/items/5bdd0de6bd339392c78f
# 文書履歴(document history)
ver. 0.01 初稿 20190812
ver. 0.04 URL追記　20230308

### 最後までおよみいただきありがとうございました。

いいね　💚、フォローをお願いします。

####  Thank you very much for reading to the last sentence.

Please press the like icon 💚　and follow me for your happy life.
Pipenvで管理しているFlaskアプリをDockerコンテナ上で動かす

僕はPipenvを愛用しているのですが，あんまりPipenvを使っている記事を見ないので普及のための記事です．今回は，「FlaskアプリをDockerコンテナ上で動かす」というありふれたというか今更？な題材を扱おうと思います．

ディレクトリ構成は以下を想定．以後， `project_name/`にいるものとします．

```
project_name/
  Dockerfile
  uwsgi.ini
  app/
    __init__.py
    app.py
```

例のごとく，アプリケーションサーバとして， `uwsgi`を使います．設定は例えば以下．

```:./uwsgi.ini
[uwsgi]
wsgi-file = app/app.py
callable = app
processess = 1

# for development
http = 0.0.0.0:5000
py-autoreload = 1

```

`./app/app.py`にはFlaskインスタンスを置いてください．僕は， `./app/__init__.py`に `create_app`関数を定義して， `./app/app.py`で呼んでます．Factory patternと言うんですかね？テスト時とかに便利らしい．

- https://flask.palletsprojects.com/en/1.1.x/patterns/appfactories/

さて， `./Dockerfile`は以下のようにします．

```docker:./Dockerfile
FROM python:3.6.5-slim-stretch

RUN apt-get update && apt-get install -y build-essential

RUN pip install pipenv
ENV PIPENV_VENV_IN_PROJECT=1

WORKDIR /usr/local/app

COPY ./Pipfile .
COPY ./Pipfile.lock .
RUN pipenv install

ENV FLASK_ENV=production
COPY ./uwsgi.ini .
CMD ["pipenv", "run", "uwsgi", "uwsgi.ini"]
```

`build-essential`ってなんなのかよくわからなかったのですが， `gcc`とかいろんなソフトウェアのインストールに必要なものの詰め合わせんなんですね．余談．

あとは， `./`でbuildしてrun．これだけで終わりです．

```bash
docker build -t myflaskapp .
docker run myflaskapp --rm -p 5000:5000
```

`http://localhost:5000`にアクセスすれば繋がるはず．
React Event + TypeScript

React`Synthetic Event`の型についてぐぐってばかりいるのでメモを残しておきます。

## Synthetic Event とは？
`onChange={event => console.log(event)}`の`event`です。

[SyntheticEvent – React](https://reactjs.org/docs/events.html)

## Synthetic Event の型

### FormEvent
```submit.tsx
import { FormEvent } from 'react';
...
const handleSubmit = (e: FormEvent) => {
...
<form onSubmit={handleSubmit}>
...
<button type="submit" onClick={handleSubmit}>Submit</button>
...
```

### ChangeEvent
```change.tsx
import { ChangeEvent } from 'react';
...
const handleInputChange = (e: ChangeEvent<HTMLInputElement>) => {
...
const handleSelectChange = (e: ChangeEvent<HTMLSelectElement>) => {
...
<input value={inputValue} onChange={handleInputChange} type="text" />
...
<select value={selectValue} onChange={handleSelectChange}>
...
```

### KeyboardEvent
```keyPress.tsx
import { KeyboardEvent } from 'react';
...
const handleKeyPress = (e: KeyboardEvent) => {
...
const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
...
<textarea
  onKeyPress={handleKeyPress}
  onChange={handleChange}
...
```

### MouseEvent
`<HTML...Element>`なしで`dataset`を参照しようとするとタイプエラーがでます。
`<button></button>`以外に`onClick`をつけることを想定するなら`<HTMLElement>`を使ってしまうと楽です。

```click.tsx
import { MouseEvent } from 'react';
...
const handleClick = (
  e: MouseEvent<HTMLButtonElement>
) => {
 e.preventDefault();
 console.log(e.currentTarget.dataset.id);
}
...
<button data-id={someId} onClick={handleClick}>click</button>
...
```
Railsでcarrierwaveを使って画像をアップロードする方法

##1,はじめに

Railsで画像投稿の機能を実装するには、**CarrierWave**というgemを使うと便利です。

##2,Gemをインストール

carrierwaveを使用するためにまずはgemをインストールしましょう。

```rails:Gemfile
gem 'carrierwave'
gem 'mini_magick'
```

mini_magickを導入することで画像の大きさをリサイズできます。

```
$ bundle install
```
ターミナルでbundle installしてgemをインストールしましょう。

##3,アップローダーを作成

carrierwaveを導入して、まずはアップローダを作成する必要があります。

```
$ rails g uploader image
```
app/uploaders/image_uploader.rb　が生成される。

##4,データベースのテーブルにimageカラムを作成

データベースのテーブルに画像保存用のカラムを追加します。

```
$ rails g migration add_image_to_users image:string
```
usersテーブルにstring型のimageカラムが追加されます。

カラムが追加されたらrails db:migrateしましょう。

```
$ rails db:migrate
```

##4.Userモデルを編集

ImageUploaderとimageカラムを紐づけます。

```rails:user.rb
class User < ActiveRecord::Base
    mount_uploader :image, ImagesUploader
end

```

`mount_uploader :carrierwave用に作ったカラム名, carrierwaveの設定ファイルのクラス名`となります。

##5,画像を送信する。

form_forで画像を送信できるようにします。

```haml
= form_for(@user) do |f|
  = f.label :image
  = f.file_feild :image
```

##6,画像を表示する

画像を表示できるようにします。

```haml:show.html.erb
= image_tag @user.image.url
```

##追記:画像のサイズを設定するには?

image_uploader.rbにサイズ変更を記述することができます。

```ruby:image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::MiniMagick
  process resize_to_fit: [800, 800]
end

```

`resize_to_fit:[高さ,横]`のサイズを指定することができます。
アコーディオンメニューをやってみた2

前回は、`CSS`でアコーディオンメニューを実装した。
今回は、`jQuery`でアコーディオンメニューをやってみた。
前回のリンクはこちら→[アコーディオンメニューをやってみた](https://qiita.com/yu-chan/items/b59895c1a4bf760ac140)

#ソース

```accordion_practice.html
<!DOCTYPE html>
<html>
<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>アコーディオンメニュー　練習</title>
	<link rel="stylesheet" href="base.css">
	<script src="https://code.jquery.com/jquery-3.2.1.js"></script>
	<script type="text/javascript">
		$(function () {
			$('#accordion p').click(function() {
				$(this).next('ul').slideToggle();
			});
		});
	</script>
</head>
<body>
	<div id="accordion">
		<p>メニュー</p>
		<ul>
			<li><a href="#">サブメニュー1</a></li>
			<li><a href="#">サブメニュー2</a></li>
			<li><a href="#">サブメニュー3</a></li>
		</ul>
	</div>
</body>
</html>
```

```base.css
#accordion {
  max-width: 300px;
}

#accordion p {
  margin: 0;
  padding: 0;
  background: #f00;
}

#accordion ul {
  margin: 0;
  padding: 0;
  list-style: none;
  display: none;
}

#accordion li {
  margin: 0;
  padding: 0;
  background: #0f0;
}

#accordion a {
  margin: 0;
  padding: 0;
  text-decoration: none;
}
```

#解説
重要なポイントは下記のコードとなります。

```js
$(function () {
	$('#accordion p').click(function() {
		$(this).next('ul').slideToggle();
	});
});
```

`p`要素をクリックした時、`slideToggle`が`ul`要素を開いたり閉じたりする。
`CSS`でプロパティを使うより、簡単に実装できた。

#参考資料
[【コピペOK】jQueryのアコーディオンメニュー実装サンプル10選！](https://www.jungleocean.com/programming/180618jquery-accordion)
【Java】Stream API/map

オブジェクト内の全ての要素を変換するメソッド

```java
public class Fruit {
	
	public static void main(String[] args) {
		
		List<String> list = new ArrayList<>();
		list.add("apple");
		list.add("orange");
		list.add("banana");
		
		List<String> ret = list.stream().map(s -> s.toUpperCase()).collect(Collectors.toList());
		ret.forEach(System.out::println);
	}
}

//出力結果は要素が大文字になる
```
（.collect(Collectors.toList());はListで返すためにつけてる）



**ラムダ式を使わなければ以下のようになる。**

```java
		List<String> ret = list.stream().map(new Function<String,String>(){
			@Override
			public String apply(String s) {
				System.out.println(s);
				return s.toUpperCase();
			}
		}).collect(Collectors.toList());
```

map()は引数にFunctionを持つ

インタフェースFunction<T,R>
T…引数の型
R…戻り値の型

applyがいきなりつかえるのは何故か？
インターフェイスFunctionの中にはapplyしかメソッドがないため(defaultは無視される)
C言語でニューラルネットワークの実装（４）〜データの準備〜

今回はデータを準備する回となります。
ニューラルネットワークに識別させるための数字のデータを用意します。「1」「2」「3」の3種類の数字を用意します。
5×5のピクセルで，次のものを「1」「2」「3」の基本的な形とします。

![sample-123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297735/a8c7f55f-ab9c-bf37-a1eb-ebfc3858c773.png)

それぞれの画像について，下の図のように黒いピクセルを1で，白いピクセルを0で置き換えます。

![sample-3-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297735/9cf6c1d0-b8a2-3d07-f8ee-7ae9a226cefd.png)

これを，txtファイルで準備します（[1-1.txt〜1-4.txt，2-1.txt〜2-3.txt，3-1.txt〜3-3.txt](https://github.com/tky1117/Neural_Network_in_C/tree/master/dataset)）。

```:3-1.txt
11100
00100
11100
00100
11100
```

この，「 `（数字の種類）-（ID）.txt` 」を読み込んでデータセットを作成していきます（[make_dataset.c](https://github.com/tky1117/Neural_Network_in_C/blob/master/multi_layer_perceptron/code/make_dataset.c)）。
今準備したデータをもとに，次の図のような濃淡のあるデータを作成していきます。

![sample-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/297735/a2002430-880a-4a5c-3de6-a0a8286b8f58.png)

```:train_data.txt
1000 // データの個数
1 // 1個目のデータの数字の種類（正解のラベル）
0.0 // この行からピクセルの値
0.0
0.0
0.2
0.2
0.0
0.0
0.0
0.0
0.5
0.0
0.0
0.0
0.0
0.5
0.0
0.0
0.0
0.0
0.5
0.0
0.0
0.0
0.0
0.9 // 1文字目終了
3 // 2個目のデータの数字の種類（正解のラベル）
...
```

ニューラルネットワークに上のtrain_data.txtの1個目のデータが入力される場合， $\boldsymbol{x} = (0.0, 0.0, 0.0, 0.2, 0.2, 0.0, \cdots, 0.0, 0.9)^{\top}$ となります。

1-1.txt〜3-3.txtまでを読み込んで，訓練用データ（train_data.txt），検証用データ（validation_data.txt），テスト用データ（test_data.txt）を作成するようなシェルスクリプト（[make_dataset.sh](https://github.com/tky1117/Neural_Network_in_C/tree/master/multi_layer_perceptron/code)）を書いたので，深く考えずともこれを実行するだけでデータが準備されます。

準備するデータの個数を変更したい場合は，make_dataset.c中の `N_train` ， `N_validation` ， `N_test` の値を変更してください。
また，文字の濃淡は，正規分布に従う乱数をもとに決めています。平均や分散を変えることで，識別問題の難易度を変えることができます。ただし，値が0を下回ったり1を超えたりする場合は，範囲内に収める必要があります。

# 続き
[C言語でニューラルネットワークの実装（１）〜多層パーセプトロンの構造と活性化関数〜](https://qiita.com/tky1117/items/ffc367e52c4a04cffa1d#_reference-ff25a31a4ae2de1c3e30)
[C言語でニューラルネットワークの実装（２）〜順伝播と損失関数〜](https://qiita.com/tky1117/items/d2847ac2c84858c7307b)
[C言語でニューラルネットワークの実装（３）〜誤差逆伝播法〜](https://qiita.com/tky1117/items/c2c69a5f69d9cf8ca751)
C言語でニューラルネットワークの実装（４）〜データの準備〜　←現在の記事
[C言語でニューラルネットワークの実装（５）〜モデルの構造と順伝播の実装〜](https://qiita.com/tky1117/items/d845040be4a13dd1133f)
[C言語でニューラルネットワークの実装（６）〜逆伝播の実装〜](https://qiita.com/tky1117/items/83403794280e74357660)
[C言語でニューラルネットワークの実装（７）〜オンライン学習と重みの初期値〜](https://qiita.com/tky1117/items/bbf250bcbd4ddae2d32e)
[C言語でニューラルネットワークの実装（８）〜ミニバッチ学習〜](https://qiita.com/tky1117/items/867f311b91fa927cacd2)
Filemakerの便利なショットカット（mac）

FileMakerのショートカットです。（随時更新）

ちなみに（mac）の場合です。

##使用例


```command-Dの場合.
「command」キーを押しつつ 「D」キーを押します。
```

##スクリプトワークスペースで便利なショートカット

|分類  |コマンド |ショートカットキー  |
|---|---|---|
|開く |スクリプトワークスペースを開く |command-shift-S |
|閉じる|スクリプトワークスペースを閉じる |command-shift-W |
|保存 |選択したスクリプトを保存  |command-S  |
|実行 |選択したスクリプトを実行  |command-R  |
|実行 |選択したスクリプトを保存後実行  |command-option-R  |
|複製 |選択行の複製  |command-D  |
|挿入  |選択行の上に空行を追加  |shift-enter  |
|挿入  |選択行の下に空行を追加  |enter  |
|コメント  |空行にコメント追加  |（空行で）#  |
|コメント  |コメント中に改行をいれる  |control-enter  |
|コメント  |選択行をコメントアウト  |command-/  |



##レイアウトで便利なショートカット

|分類  |コマンド |ショートカットキー  |
|---|---|---|
|選択 |全てを選択 |command-A  |
|選択 |同じものを選択  |option-command-A  |
nginxでAPIとSPAの両方を配信する

APIとSPAの両方をnginxで配信すれば，CORS問題が起きない（はず）．初心者の僕にはわからないけど，一般的にもやられているのだろうか？今回は例として，Flask製のAPIとVue.js製のSPAでの場合について書く．基本的には他の組み合わせでも同じはず．

dockerで以下のイメージを用意する．

- application server (uwsgi)
- web server (nginx)
- db (mariadb)

ディレクトリ構成は以下を想定．

```
project_name/
  web/
    api/
      Dockerfile
      uwsgi.ini
      api/
    spa/
      dist/
    conf/
      default.conf
  data/db/
  docker-compose.yml
```

ここからは `project_name/`にいることを想定します．

```docker:./docker-compose.yml
version: '3'
services:
  api:
    build: ./web/api
    ports:
      - "5000:5000"
    depends_on:
      - db
    volumes:
      - ./web/api/api:/usr/local/api/api
  nginx:
    image: nginx
    volumes:
      - ./web/conf/default.conf:/etc/nginx/conf.d/default.conf
      - ./web/spa/dist:/usr/share/nginx/html
    ports:
      - "8080:80"
    links:
      - api # いらないかも
  db:
    image: mariadb
    volumes:
      - ./data/db:/var/lib/mysql
    ports:
      - '3306:3306'
    environment:
      - MYSQL_ALLOW_EMPTY_PASSWORD=1
    command:
      - --character-set-server=utf8 # これと
      - --collation-server=utf8_general_ci # これは大事．mb4は日本語文字化けした
```

buildはAPIだけでいい．僕はPipenvを愛用しているのですが，Pipenvを使ったFlask製APIのDockerfileの書き方についてはまた書こうと思います．

本番ではdbコンテナ（もしかしたらnginxも）は立てないと思うので，その場合，APIだけ立てればいい．docker-composeの恩恵？余談でした．

nginxの設定ファイルは以下のようにした．僕はnginx.confは触らずに（設定項目をよくわかっていない），default.confだけ書き換えることにしました．

```nginx:./web/conf/default.conf
upstream api {
    server api:5000; # ここのapiはdockerのservice名
}
server {
    listen 80;

    location /api {
        include uwsgi_params;
        uwsgi_pass api;
    }

    location / {
        root /usr/share/nginx/html;
        try_files $uri $uri/ /index.html;
    }
}
```

`upstream api`と `uwsgi_pass api` の `api`は同じであればなんでもいいです多分．

SPA (Vue.js)側で，apiを呼び出すと思うのですが，上記の設定だと，この時のアドレスは `/api`になる． `http`とかもいらないです．ここ大事．

Vue.jsだと以下のように設定を分けるといいです多分 （ `process.env.VUE_APP_API_URL`を参照している場合）．

```:.env.local
VUE_APP_API_URL: http://locahost:5000/api
```

```:.env.production
VUE_APP_API_URL: /api
```

これで， `yarn build --mode production`とすれば，`./web/spa/dist/`にproduction用のSPAができます．この辺の話は以下に書いてあります．

- https://cli.vuejs.org/guide/mode-and-env.html#modes

さて，ここまできたら， `./`で，

```bash
docker-compose build
docker-compose up -d # ログ見たかったら-d消す
```

とすれば全て立ち上がるはず．

ブラウザで `http://localhost:8080`にアクセスすると，vue appが表示されるはずです．

## 終わりに

今回の話はweb serverとapplication serverを一つのマシン上で動かすことを想定しているけど，多分世の中そんなことはあんまりやられていないんじゃないかと思う．wordpressみたいな立場をとれば使えるかも．適宜一般化したので，動かない！とかなったらコメントしてください！読んでいただきありがとうございました．

## 余談: Vue RouterのHistory modeを使っている場合

Vue RouterのHistory modeを使っている場合，以下のようにしないと404が返ってくるので注意．

```nginx
location / {
    root /usr/share/nginx/html;
    try_files $uri $uri/ /index.html;
}
```

ここに記載がある: https://router.vuejs.org/ja/guide/essentials/history-mode.html#%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%AE%E8%A8%AD%E5%AE%9A%E4%BE%8B
System.Randomがimportできない

# はじめに
技術書の写経していてSystem.Random使うところでエラーが出てきて詰まった。

# 環境
macOS Mojave 10.14.6
stack Version 2.1.3 x86_64

# 原因
技術書ではインストーラを使用して導入しているが、それが面倒だったのでHomebrewとstack使ってた。

# 解決策
`$ stack install random`
を打つだけ。
たぶん一瞬で終わります。
他のサイトや記事では
`$ cabal install random`
と書いているものもありますが、今回stackで管理しているのでそちらでinstallするのが筋だろうと思いstackで打ってます。
もちろんstackを使っていなければそちらで良いと思います。

# 終わりに
デフォルトで入っていそうな名称(System.Random)だったのでそれも入れなきゃいけないのかとちょっと驚きました。
ActiveRecordのdistinctメソッドを使って、一意なデータのみを取得する方法

一意なデータを取ってくる方法を探していた時、ActiveRecordのdistinctメソッドを発見したため、実際どのようなSQLを発行しているのかし調べてみました。
下記のようなテーブルがあったとします。Userテーブルが親でTaskテーブルは子の状況です。

### Userテーブル

| id  |name   |    color    |
|:-----------------|------------------:|:------------------:|
| 1   |Bob    |     blue        |
| 2   |Tom    |     red     |
| 3   |Emi    |     black        |
| 4   |Rick   |     red         |
| 5   |Goto   |     red       |
| 6   |Alice  |     black       |

### Taskテーブル

| id  |user_id|    task    |
|:-----------------|------------------:|:------------------:|
| 1   |1      |     掃除        |
| 2   |4      |     宿題     |
| 3   |1      |     風呂掃除        |
| 4   |6      |     買い物         |
| 5   |3      |     昼寝     |
| 6   |4      |     野球       |

```
User.all.distinct
```

Userテーブルの全てのデータを取得し、そこにdistinctメソッドを実行しました。以下のようなSQLになります。

```
SELECT  DISTINCT `users`.* FROM `users`
```

テーブルから取得した列に対して重複を省いています。今回の場合、全ての列を取得しているため、重複が発生することはありません。(そもそもidは一意だから。)

```
User.select("color").distinct
```

取得する列をcolorで絞ってみましょう。

```
SELECT  DISTINCT `users`.`color` FROM `users`
```

すると、取得できるデータはblue、red、blackの3つのみになるはずです。distinctメソッドを使用することで6つ全てのデータを取得するのではなく、値が重複している分のredとblackのデータは除かれます。これはUsersテーブルにあるcolorの列に対してDISTINCTを実行しているからです。

では結合(inner join)させた場合はどうなるでしょうか？タスクを作成しているユーザーのみを取得したい時、下記のようなものができます。

```
User.joins(:tasks).distinct
```

```
SELECT  DISTINCT `users`.* FROM `users` INNER JOIN `tasks` ON `tasks`.`users._id` = `users`.`id`
```

取得するデータは4つになるはずです。取得したデータの中でUsersテーブルのレコードが同じものがあった場合、その重複分は排除されます。
AWSを無料でお勉強：コンソールログインを検知したい（その４）

お約束になってきました、コンセプトから。

###コンセプト
・お金かけてまでやりたくないので基本的に無料でAWSを勉強する
　→ちょっとしたサービスを起動すると結構高額になりやすい。
・高いレベルのセキュリティ確保を目指す
　→アカウントを不正に使われるととんでもない額を請求されるので防ぐ

###CloudWatchLogsでメトリクスフィルター作成
Cloudwatchのログからメトリクスフィルターを作成します。

```
{ $.responseElements.ConsoleLogin = "Success" && $.sourceIPAddress !="***.***.***.***" }
```
![201908121.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/ab6a1362-6be1-489c-cd2e-8162254c14d3.png)

ソースIPアドレスは自分がアクセスしているものを
http://whois.domaintools.com
で確認しておきます。コンソールログインのIPアドレスをwhoisで確認して、自分のプロバイダーになっていれば、プロバイダーのグローバルIPが引けていることになるので大丈夫でしょう。

![201908122.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/4cca0d68-83d5-95d8-5d78-016d8b48b414.png)
無事に作成できました。


###アラームを設定
そのままアラーム作成します。
![201908123.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/a7216a2b-a3f8-4c62-5291-ba241d825320.png)

期間は１分にします。これ以上短いと有料になるみたいです。

![201908124.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/d9310c3e-9f62-1884-62ed-e95526b02b2c.png)
検知は0にします。１回でもあってはこまるので、0より多い場合に検知します。

![201908125.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/480659/cdbbde74-9ff5-b9ea-997e-6ad587f1478b.png)
通知先メールをセットします。

これで完了です。試しにスマホからログインしてみると、しっかりと通知メールが飛んできました。うまく検知できています。

ちなみに、予想通り課金されました。課金アラームで0.01ドルになっています。時間にして１日分なので、どんなに使っても１ドルはいかない気がしますが、しばらく様子を見てみようと思います。課金アラームの閾値も０ドルから１ドルにしないと意味ないです。。。
Gitコマンド備忘録

# はじめに
様々な端末で（といってもWindows）様々なGitリポジトリにアクセスすることがあり、その度にセットアップすることが多いので、自分用に備忘録として残しておきます。

# 最初にやること
## ユーザ情報設定
```bash
git config --global user.name "Jushi JUSHI"
git config --global user.email "jushi@example.com"
```

## (あれば)Proxy設定
全てのリモートリポジトリがProxyを挟むのであればいいのですが、こっちは社内なのでProxy不要、あっちは社外なのでProxy必要、
なったりするので、極力ドメイン別で設定しています。

```bash
# プロキシ設定
git config --global http.{{url}}.proxy {{ProxyサーバーのURL}}

# オレオレ証明書を利用しているなど、SSL認証ではじかれる場合
git config --global http.{{url}}.sslVerify false
```

# clone
## HTTPS
```bash
# 認証不要
git clone https://github.com/{{user}}/{{repo}}.git {{dir}}

# 要認証
git clone https://{{account}}:{{token}}@github.com/{{user}}/{{repo}}.git
```

## SSH
事前にRSAを作成してGitHubに登録(Personal settings -> SSH and GPG keys)した上で、

```bash
# gitbash上でssh-agentを起動
eval `ssh-agent`

# RSAを登録
ssh-add ~/.ssh/id_rsa

# clone
git clone git@github.com:{{user}}/{{repo}}.git
```

(これって毎回やらなければならないのでしょうか…？)

# log
```bash
# ログを各1行でグラフィカルにデコレーションして全部表示
git log --oneline --graph --decorate --all
```

diffやらmergeやらrebaseやらは先人の皆様がたくさん書いていらっしゃるので、ここまで。

# いつもお世話になっているサイト
* gitのproxy設定をリポジトリごとに変える方法
 * https://qiita.com/emudome/items/2e7942104d66d59fd577
OTTO環境セットアップ(Arduino)  

サマーイベント用に環境セットアップ方法を説明

# 1. Arduinoインストール

https://www.arduino.cc/en/Main/Software

### 1.1: 初心者の方はWindows Installer使用を推奨（下図赤丸をクリック）

![arduino_install.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438528/8d93254a-e163-b48b-7c47-5d3a6476b05f.png)

### 1.2: "just download"もしくは”CONTRIBUTE & DOWNLOAD"をクリック

![arduino_install_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438528/56aaedf6-5b89-7208-67e2-81f6edf0982f.png)


# 2. CH34xドライバインストール (互換nano利用時）

http://www.wch.cn/downloads/CH341SER_ZIP.html

# 3. OTTO DIYソース(ZIPファイル)ダウンロード

https://github.com/OttoDIY/DIY

参考：初心者向けのGithubからのZIPファイルダウンロード方法
https://qiita.com/okamot_dmc/items/c6cd951a75449c201d9a

# 4. OTTOライブラリのコピー

- 3でダウンロードしたZIPファイルを解凍
- 解凍されたフォルダ内の"DIY-master\libraries"を開く
- librariesフォルダ内のすべてを<ユーザ名>\Documents\Arduino\librariesにコピー

# 5. Arduino接続テスト

Arduino nanoを所定のUSBケーブルでPCに接続し、
デバイスマネージャにCH340のCOMポートが追加されていることを確認。
（下画面のように追加されない場合はUSBケーブルを差し直し、CH34ｘドライバ再インストール、
PC再起動を実施する。それでもNGの場合はスタッフにヘルプ求める）

![com_port.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438528/3d863db4-5c98-0967-a5d8-e756ab6f3ea3.png)

# 6. Arduinoツールセットアップ＋書き込みテスト

Arduinoを起動し、DIY-master\Otto_Footalign\Otto_Footalign.inoを開く。

Arduinoのツールメニューを開き、下記４項目を設定する。

　ボード：Arduino nano
　プロセッサ： ATmega328P
　シリアルポート： COMx (xはデバイスマネージャで追加されたポート番号を選択）
　書込装置：USBasp

![arduinoツールセットアップ.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/438528/48acd719-7348-33c2-7fcc-40b0fe8d1aec.png)

「スケッチ」メニューをクリックし、「マイコンボードに書き込む」を選択する

"ボードへの書き込みが完了しました"が表示されれば書き込み成功。
そうでない場合は失敗しているので、ツールの設定や接続を見直す。

以上
Macで閉じるボタンを押してもアプリが終了しない件

# 閉じるボタンでアプリが終了しない？

今年の初めまで私はUbuntu (90%), Windows (10%)ぐらいの割合でOSを使ってきており、
MacOSは基本的に使ったことはありませんでした。
Windowsマシン (Ubuntuで書き換えていましたが)が壊れてしまったのを機に、MacOSを試したいという思いがあり、Macを買いました。

使い始めて気持ち悪いと感じたのが、左上の閉じるボタン「赤いボタン」を押して、アプリを終了しようとしたときのこと。
確かにウィンドウは閉じたのですが、Dockのアイコン化にドットが残ったまま。
閉じるボタンを押してもアプリは終了しないということがわかりました。
アプリを終了するにはアイコンを右クリックしてQuitで終了できます。

ただ、UbuntuやWindowsから来た人間としては、「閉じるボタンを押したらアプリは終了やろ」って思いました。どういう経緯でこうなっているのか調べてみました。

# なぜこういう挙動をするのか？
[この記事](https://www.howtogeek.com/279086/why-do-mac-apps-stay-open-when-i-hit-the-red-x-button/)によると、Windowsでは一般的に1アプリ = 1ウィンドウなのに対して、Macでは1ドキュメント = 1ウィンドウというイメージみたいです。なので、ウィンドウを閉じてもメニューバーは残りっぱなしで、このメニューバーから新規ウィンドウが簡単に作れるようになっています。
このような仕組みになっているのは初期のMacに遡ります。[StackExchangeの投稿](https://unix.stackexchange.com/questions/4618/why-mac-applications-never-get-closed)にも書かれている通り、初期のMacでは同時に複数アプリケーションを起動することはなく、1アプリのみというのが基本でした。なので、閉じるボタンを押してもアプリをメニューバーとして残しておいて、いつでもドキュメントを作れるようにしてありました。
初期のMacの思想がそのまま今も受け継がれているということなんですね。

# 閉じるボタンを押すと閉じるアプリもある
とは言っても例外はあります。例えば「Notes」というメモアプリや「System Preferences」は閉じるボタンで終了することができます。[この動画](https://www.youtube.com/watch?time_continue=374&v=GaEp6Rlc8FE)によると、単一ウィンドウを前提としているアプリは閉じるボタンで終了するようになっているのではないかということです。

# 最後に
[RedQuits](http://www.carsten-mielke.com/redquits.html)のようなアプリはありますが、
基本的には「郷に入りては郷に従え」ということで、Macの文化に慣れていくのが良いかと思います。
【コマンド補完】MacOSでawscliのTabキー補完できるようにする

awsのコマンドは沢山あり、かつサブコマンドは大体長いので覚えるのも、タイピングするのも面倒くさいですよね。
他のコマンド同様にTabキー補完できるようになれば、いくらか楽になります。楽なる方法を説明したいと思います。

# 環境
- MacOS Mojave 10.14.6
- Bash 3.2.57
- Homebrew 2.1.9

# 設定方法
今回はBashにのみフォーカスします。他のシェルについてもパッケージ名やディレクトリ名が違うだけで、同様の手順を踏めばTab補完ができると思います。
brewコマンドはインストール済みであると想定して話を進めていきます。まだインストールしていない方は[こちら](https://brew.sh/index_ja)を参考にしてインストールしてください。

## パッケージインストール
### bash-completion

```bash

$ brew install bash-completion
```

### awscli

```
$ pip install awscli
```

または

```
$ brew install awscli
```

## ~/.bashrcの編集
`~/.bashrc`または`~/.bash_profile`を編集してBashの補完を有効にします。

```bash
if [ -r /usr/local/etc/bash_completion ]; then
    . /usr/local/etc/bash_completion
fi
```

```bash
$ source ~/.bashrc
```

## シンボリックリンクの作成
`/usr/local/etc/bash_completion.d`下にawscliの補完用スクリプトのシンボリックリンクを作成します。

```bash
$ which aws_bash_completer
/usr/local/bin/aws_bash_completer

$ ln -s /usr/local/bin/aws_bash_completer /usr/local/etc/bash_completion.d/aws
```

# おわりに
これでシェルを再起動すれば、Tab補完ができるようになります。
他のコマンドの補完もしたい時には、補完用スクリプトのシンボリックリンクを`/usr/local/etc/bash_completion.d`下に作成すればOKです。