OmniAICreator/Qiita-1.07M huggingface dataset:
公式チュートリアルに沿ってTerraformでEC2インスタンスを立ててみるメモ

# メモ
- EC2インスタンスを一台作成する
- `参考` 記載のURLの通りに実行したメモ

## インスタンスの構築

```zsh
# 作業用ディレクトリ作成
% mkdir terraform-test2
% cd terraform-test2

# configuration codeファイル（日本語訳不明）作成
% touch example.tf

# デプロイするサービスプロバイダの種類（AWS）やリソースの情報を記載する（AMI IDは環境によって有効な値に読み替えること）
% vim example.tf
provider "aws" {
  profile    = "default"
  region     = "ap-northeast-1"
}

resource "aws_instance" "example" {
  ami           = "ami-2757f631"
  instance_type = "t2.micro"
}

# 初期化コマンド
# AWSとの連携に必要なファイル類をダウンロードするらしい
% terraform init

# フォーマット & バリデーション
# ファイルのフォーマッティングをしてくれる。インデントとか
% terraform fmt

# バリデーション
% terraform validate

# リソース作成
# `yes` と入力を求められるプロンプトが表示される
% terraform apply
...

# リソース確認
%  terraform show
```

## インスタンスのタイプ変更

```zsh
# t2.micro -> t2.large に変更
% vim example.tf
provider "aws" {
  profile    = "default"
  region     = "ap-northeast-1"
}

resource "aws_instance" "example" {
  ami           = "ami-2757f631"
  instance_type = "t2.large"
}

# 変更実行
# 勝手にインスタンス止めて、起動させてくれる。すごい。
% terraform apply
```

## インスタンスの削除

```zsh
% terraform destroy
```

# 参考
Build Infrastructure | Terraform - HashiCorp Learn https://learn.hashicorp.com/terraform/getting-started/build
【自分用】ピカソの洗礼名を覚える為のタイムアタックプログラムと、作って学んだことをメモ

### コード
```Ruby:picass.rb
require 'date'

class Array
  def average
  self.inject(:+) / self.length
  end
end

christian_name = "パブロ・ディエゴ・ホセ・フランシスコ・デ・パウラ・ファン・ネポムセーノ・マリア・デ・ロス・レメディオス・クリスピン・クリスピアーノ・デ・ラ・サンティシマ・トリニダード・ルイス・イ・ピカソ"

num = 1
results = []
while num <= 10 do
  puts "#{num}回目:ピカソのフルネームを入力してください"
  started_at = Time.now
  christian_name_input = gets
  while christian_name_input.chomp != christian_name do
    puts "#{num}回目:間違ってます！きちんとピカソのフルネームを入力してください！"
    christian_name_input = gets
  end
  finished_at = Time.now
  puts "#{(finished_at - started_at).round(2)}"
  results.push((finished_at - started_at).round(2))
  num+=1
end
puts "---結果------------------"
results.each_with_index do |result, i|
  puts "#{i+1}回目：#{result}秒"
end
average = results.average
puts "平均入力時間：#{average.round(2)}秒"
puts ""
puts "あの世のパブロからのコメント"
if average > 20
  puts "「ナニ サイゴマデ ヤッテンダヨ。 ヒマカヨ、、」"
elsif average <= 20 && average >= 10
  puts "「アンタ ダイブキモチワルイネ、、」"
elsif average <= 10
  puts "「コピペデショ？、、チガウノ？ヒエッ、、」"
else
  puts "「ナニカガ オカシイ」"
end
puts "------------------------"

```
### 書いて学んだこと
既存のクラスを任意の場所で開いて、メソッドの追加や修正が自由に行えます。
**オープンクラス**といいます。

```Ruby
class Array
  def average
  self.inject(:+) / self.lengt
  end
end
```
それから、Arrayクラスのinjectメソッドは、演算子をsymbolで渡すことができます。
こんな感じでスッキリ書けます。
`self.inject(:+) #全部足す`

getsでキーボードから入力した値には改行が入ってきますが、chompで消せる。
また、数字を入力しても数値ではなく文字列として入ってくるので注意。

```Ruby
  picass_input = gets
  while picass_input.chomp != picass_fullname do
    puts "#{num}回目:間違ってます！きちんとピカソのフルネームを入力してください！"
    picass_input = gets
  end
```

何らかの日時を代入する変数名を、今まではfinish_timeみたいにしてたが、finished_atのようにした方がかっこいい。
あと標準出力用のメソッドは色々あります。
[参考]https://qiita.com/naoge/items/f5d84581d3a301a9c22f

```Ruby
  finished_at = Time.now　# finish_timeはダサい
  puts "#{(finished_at - started_at).round(2)}"
```


switch文のwhen節の条件を範囲にしたい場合は、こんな感じで範囲オブジェクトが使える。

```Ruby
score = 65
case score
when 0..59
  puts "C"
when 60..79
  puts "B"
else
  puts "A"
end # B
```
今回は小数が入ってくるので、仕方なく関係演算子を使った。
（59.01だとelseに入ってしまうので）

```Ruby
if average > 20
  puts "「ナニ サイゴマデ ヤッテンダヨ。 ヒマカヨ、、」"
elsif average <= 20 && average >= 10
  puts "「アンタ ダイブキモチワルイネ、、」"
elsif average <= 10
  puts "「コピペデショ？、、チガウノ？ヒエッ、、」"
else
  puts "「ナニカガ オカシイ」"
end
```
プログラミング学習まとめ

【趣味で始めたプログラミングの勉強の忘備録的なまとめ】

　普段仕事でCOBOLを使用していましたが、
サーバーの知識を深めたり仕事以外の言語に興味がありました。
　また、模型趣味のホームページ作成に挑戦したくもあり、
サーバーサイド言語フロントエンド言語の勉強に取り組みました。
　牛歩ではありましたが、今までの内容を振り返りたく記事にまとめてみました。


・2019年1月〜6月頃
主に学んだもの　→HTML CSS Ruby RubyOnRais 

　スキルハックスを参考に勉強開始。　
環境はAWSのcloud９を利用。
　HTMLとCSS、Bootstrapを利用してポートフォリオサイトの作成。
Rubyでメモアプリ作成。
　メモアプリを元にRubyOnRaisでメモアプリのwebアプリケーション作成、
herokuにデプロイ。


・2019年8月〜12月頃
主に学んだもの　→PHP　javaScript
　一つの言語を極めた方が良いという意見をツイッターで多く得たが各言語の違いを知らずに
絞るのは難しく、他の言語を知る機会が無くなるので取り敢えず色んな言語に触れて後から一つに絞ろうと決める。
　Progateに登録してPHPの学習を始める。同じサーバーサイドの為、Rubyの時よりは覚え易かった。PHPを一通り勉強してみたが思ったよりフロントエンド言語関係を忘れている事に焦り、再度フロントエンドの復習。Udemyにてフロントエンド言語の動画も購入し視聴。
　その後デイトラ30日チャレンジを参考にProgateでjavaScriptの学習を開始。


・2020年1月〜現在
主に学んだもの　→Python
　年始の時間を利用して模型のホームページ作成を開始。
エディターはVScodeを利用。ProgateのHTML講座をVScodeの書き写して復習も。またUdemyやgoogleの動画を視聴してみたく、英語の勉強も少しづつ始める。
　息抜きに『痛快コンピュータ学』を読みました。コンピュータの歴史や基礎を初心者にもわかりやすく解説してあり、情報科学の基礎に興味を持つ良い機会となりました。
　以前からデータサイエンティストについて気になっていたの事もあり、かつ何故機械学習に強いのかについても興味があった為、Pythonの学習を始める。 
　Progate、Udemyを利用して現在勉強中。エディターはVScode、PyCharm。後々は統計学等も本格的に学んでみたいと思います。
Watson StudioのDecision Optimizationで看護師のシフトの最適化問題を解く

Watson Studio では最適化エンジンの Decision Optimization(CPLEX)をCloud環境で使用することが可能です。本記事では最適化の問題としてよく出てくる、看護師のシフトの最適化をご紹介します。

# 看護師のシフトの最適化
複数の看護師のシフトを組む際に、労働時間や個々の看護師のスキル、必要となるコスト等を考慮して、いかに最適なシフトを組むか、という問題になります。有限のリソースをタスクに最適に割り当てるという同様の作業にも応用可能なソリューションになります。

今回は以下リンク先のサンプルをベースにして、Jupyter NotebookでPythonのコードを実装しました。

http://ibmdecisionoptimization.github.io/docplex-doc/mp/nurses.html

理解しやすいようにコードをシンプルにし、制約条件も簡略化しています。サンプルには無いですが、最適化したシフトのガントチャートを作成しました。


# 手順
Watson Studioで新規Notebookを作成します。作成時には以下のURLを指定し、runtimeには「Default Python 3.6 XS + DO」を指定します。

https://github.com/schiyoda/DO_Nurse_Assignment/blob/master/Nurse%20Assignment.ipynb

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/6768a95e-e127-8d91-a944-cb58c38e7a5d.png)

コードの詳細はNotebookをご参照ください。
大きな流れとしては、必要なデータを準備した上で、以下のように、一般的な最適化問題の解放と同様です。

1. 決定変数の定義
32人の看護師を１週間の36シフトに割り当てることになります。看護師とシフトの全ての組み合わせについて変数を定義し（32x36=1152個の変数を定義）、各々の変数に1（勤務）か0（休暇）を割り当てる問題とすることができます。

2. 制約の定義
制約としては以下のようなものを設定しています。全ての制約を定義すると1221個の制約が設定されたことになります。
 - 看護師の１週間の労働時間を40時間以下にする
 - 各看護師に休暇と設定された曜日は勤務できない
 - 時間が重複しているシフトに同一看護師は割り当てられない
 - シフト毎に定義された最小/最大の人数を満たす看護師を割り当てる
 - シフト毎に定義された必要スキルを保有する看護師を割り当てる
 - 特定のペアの看護師を同一のシフトに割り当てる（新人とその指導者等）
 - 特定のペアの看護師を別シフトに割り当てる（相性を考慮）


3. 目的関数の定義
看護師毎に定義された時給があるので、１週間の総コストを計算し、総コストを最小化することを目的関数として定義します。

4. 問題を解く

Notebookを最後まで実行すると以下のように最適化されたシフトがガントチャートで表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/235649/3d29c8eb-0984-671c-b41a-df43d02369dc.png)
WebSocket備忘録

###はじめに
javascript歴3,4ヶ月の初心者です。
自分の備忘録用に書いていますが、本記事で指摘事項などありましたらコメントにて教えていただければ幸いです。
#WebSocket通信でハマったこと
WebSocketとnode.jsを使っでソケット通信の勉強をしている時、node.jsでサーバーを立ち上げずに以下のコードを実行すると、エラーになる。

```websocket.js
//これがエラーになる
var ws = new WebSocekt('ws://127.0.0.1:50000/');
window.addEventListener('open', function(e) {
    console.log('Socekt Open!');
});
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436603/43de86a3-3c3a-d5c7-8e25-4b416b9a612d.png)
このエラーが発生した後にサーバーを起動してもつながってはくれいない。
サーバーが起動していなくてもリトライをして、繋ぎに行く処理を作りたかった。
##解決案
####その１
脊髄反射でtry~catch文でエラーのところを囲めばどうにかなるかなと思って実行。

```websocket.js
function socketConnect() {
    try{
        var ws = new WebSocekt('ws://127.0.0.1:50000/');
    } catch(e) {
        socketConnect();
    }
    window.addEventListener('open', function(e) {
        console.log('Socekt Open!');
    });
}
```
try~catchでエラーになったら再帰的に呼び出してもう一回同じ処理を実行するみたいな感じで書いてみたが、エラーは相変わらず出るし再帰呼び出しもされていなかった。
####その２
WebSocketのイベントにあるcloseイベントでエラーを取得する。

```websocket.js
 function socketConnect() {
    var ws = new WebSocekt('ws://127.0.0.1:50000/');
    window.addEventListener('open', function(e) {
        console.log('Socekt Open!');
    });
    window.addEventListener('close', function(e){
        socektConnect();
    });
}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436603/c3134d08-5be1-d78a-440c-d0becfd00aa0.png)
エラーは変わらず出続けているけど、再帰呼び出しはできた！
#まとめ
[リファレンス](https://developer.mozilla.org/ja/docs/Web/API/CloseEvent)によると次のように書かれている。
>1006	Abnormal Closure	予約済。ステータスコードが必要なときに、接続が異常終了した (つまり、クローズフレームが送信されていない) ことを示すために使用されます。

つまり、サーバーを立てずに繋ぎに行こうとした場合このコードが取れるらしい。このコードの時は再帰呼び出しをするようにすれば、上記のエラーが起きてもサーバーが立つまで再接続ができる。
他にも成功時には"1000"、プロトコルエラーの時は"1002"といったように、クローズイベントのコードごとに対応するエラーがある(ユーザで設定することも可能)。
Azure VMのコピー

AzureのVMをコピーしたくて方法を調べました。
情報が少なかったので、試してみた結果をメモ代わりに。

# コピーする前に必要なこと

以下の手順ですが、いずれも「コピー元のVM」の構成を覚えておく必要があります。
VM作るときに指定するやつです。サイズとかネットワーク規則設定とか。

# 方法１：スナップショットから

画面だけで完結するので、1回しかコピーしないのであればこの方法が一番楽。
VM停止しなくてもコピーできましたが、念のためVMは停止してからのほうが良いと思います。

なお、スナップショットから直接VMを作れるという記事を見つけましたが、本記事執筆時点ではできませんでした。
なんか変わったんですかね？今はスナップショット→ディスク→VMじゃないとダメです。

#### 1. OSディスクのスナップショットを取る

1. 対象のVM管理画面で、[設定] - [ディスク] から、OSディスクを選択する。

2. [＋スナップショットの作成]をクリックする。

3. スナップショットの名前を適当に付ける。
   アカウントの種類は、この時点ではPremiumでもStandardでも何でも良い。
   設定したら、スナップショットを作成する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/45ffcad7-2612-17b4-ce61-f9f68b6ffbbf.png)

#### 2. スナップショットからマネージドディスクを作る

1. [ホーム] > [ディスク] の画面で、[＋追加]をクリックする。

2. こんな感じで入力して、作成する。
   ディスク名：適当
   ソースの種類：「スナップショット」を選んで、「ソースのスナップショット」に作成したスナップショットを指定。
   サイズ：スナップショットのサイズに合わせる。この時、**PremiumディスクにするかStandardディスクにするかを指定**すること。
   （この後作る**VMのサイズがPremium非対応**なのに、ここで**PremiumディスクにするとVMを作成できない**）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/0df6d9c5-590a-c55c-7b01-69edc8b30f1f.png)

#### 3. VMを作成する

1. 作成したマネージドディスクの管理画面から、[＋VMの作成]をクリックする。

2. イメージに、作成したマネージドディスクが設定されているはず。
   あとは、コピー元のVMと同じように設定して、VMを作成すれば完成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/efc32f85-29fd-48ff-51eb-e0b6c10130ac.png)


# 方法２：Azure PowerShellから

Microsoft Docsの以下の記事の内容で、複製できることを確認しました。

+ Azure CLI と Managed Disks を使用して Linux VM のコピーを作成する
  - [https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/copy-vm] (https://docs.microsoft.com/ja-jp/azure/virtual-machines/linux/copy-vm)

VMを何台もコピーしたい場合は、シェル組んでもよさそうですね。


# 方法３：キャプチャから

**注意：この方法は元のVMが使えなくなります。**

「Azure VM 複製」でググると、この方法がいっぱい出てくるんですよね。
複製、たしかにできるっちゃできるんですが、複製元VMが使えなくなります。（起動できない）

本来やりたい「コピー」ではないのですが、ざっくり説明しておきます。

#### 1. VMのキャプチャを作成

「キャプチャ」ボタンを押して、次の画面で指示通り入力していきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/3b2b5ad0-1e6b-f169-da25-d6a2a92967e9.png)

#### 2. キャプチャからVMを作成

作成したキャプチャから、[＋VMの作成]をクリックする。
あとは、普通のVM作成と同じ感じで。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517338/ca917055-ef0e-c919-0d77-98cea684d3bd.png)

# まとめ

+ 方法１
  - 突発的にVMをコピーしたくなった時
+ 方法２
  - コピーVMをまとめて何台も作りたい時
+ 方法３
  - VMのテンプレートみたいなものを用意して、まとめて複数台作る時？？

って感じでしょうか。
方法３もPowerShellからできると思うんですが、そうすると２と３の違いがよくわからない・・・。

あと、方法１と方法２は画面かコマンドかの違いだけでほぼ同じことをやっているんですが、方法１は「スナップショット」を作っていて、方法２は「OSDiskをコピー」してます。
（スナップショットはマネージドディスクではないので、そのままVMのOSDiskにできない）

う～ん・・・もうちょっと簡単にならないんですかね・・・
次回（があれば）、自動化するシェルなんて作ってみようかと思います。
Laravel7.xでフロントをReactに切り替える方法

#概要
バックエンドにLaravel、フロントにReactを使ったWebアプリケーションを作りたい場合の簡単な切り替え方法。
Laravel7.xから若干手順が変わっていたので備忘録として残しておく。

#手順
```
// Laravel7.x以降
$ composer require laravel/ui
$ php artisan ui react

// Package.jsonにReact関連の依存関係が追加されているのでインストールする
$ npm install

// コンパイルできるか確認
$ npm run dev
```

Laravel5.5から導入された`php artisan preset react`ですが、Laravel7から`php artisan ui react`に変更になっているようです。


#参考にさせて頂いた記事
[JavaScript & CSS Scaffolding - Laravel - The PHP Framework For Web Artisans]
(https://laravel.com/docs/7.x/frontend#introduction)
[reactjs - Laravel 5.4 can't run "php artisan preset react" comand - Stack Overflow]
(https://stackoverflow.com/questions/48381322/laravel-5-4-cant-run-php-artisan-preset-react-comand)
[Laravel Frontend Presets - Taylor Otwell - Medium]
(https://medium.com/@taylorotwell/laravel-frontend-presets-eca312958def)
Vue.jsのDocker開発環境構築手順まとめ

Vue.jsのDocker開発環境構築手順をまとめる。(備忘録のN番煎じ記事)
前提条件：Docker,docker-composeをインストール済みであること。

### 事前準備(Dockerfile,docker-compose.ymlを作成する)

```shell
mkdir 任意のディレクトリ
cd 任意のディレクトリ
vi Dockerfile
vi docker-compose.yml
```

Dockerfileとdocker-compose.ymlに、以下を記述する。

#### Dockerfile

```dockerfile
# ベースイメージ
FROM node:13.10.1-alpine3.11
# vue-cliインストール
RUN npm install --global @vue/cli
# 作業ディレクトリ指定
WORKDIR /myprojects
```

#### docker-compose.yml

```yml
version: '3'
 
services:
  app:
  	# ビルドパス
    build: .
    # ポート指定
    ports:
      - "8080:8080"
    # マウント指定
    volumes:
      - ".:/myprojects"
    # 起動状態のままにする
    tty: true
```

### コンテナを作成・起動して、コンテナ内に入る

```shell
docker-compose up -d
docker-compose exec app ash
```

### Vueアプリを作成する

```shell
vue create app
```

* 設定は、各自の要件に合わせて選択する。

### アプリを起動・動作確認する

コンテナ内で、以下を実行する。

```shell
cd app
yarn serve
```

`http://localhost:8080`にアクセスする。

以下の画面が表示される。
<img width="1163" alt="vue-sample.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586535/0d428ad8-39e2-2c36-1702-628085c21e8b.png">
N+1問題とは？

#はじめに

よく耳にするけど「N+１問題」っていったい何？？
どうすれば対処できるの？？
となったのでまとめてメモ。

#N+1問題って？

N+1問題とは、SQLが必要以上に発行されてしまい、パフォーマンスが低下してしまう問題のこと。
??????

##つまりどういうこと？？

例えば、
UserモデルとMicropostモデルがあり、
Userが複数のMicropostを持っているとします。

```app/models/user.rb
class User
 has_many :microposts
end
```
```app/models/micropost.rb
class Post
 belongs_to :user
end
```
そしてMicropost一覧ページでuserを表示するとします。

```app/controllers/micropost_controller.rb
class MicropostsController < ApplicationController
  def index
    @microposts = Micropost.all 　①
  end
end
```
```app/views/microposts/index.html.erb

@microposts.each do |micropost|
  micropost.content
  micropost.user.name  ②ここで発生！
end

```
①ここでまずMicropostモデルを全て取得
②ここでUserテーブルへのアクセスをMicropostの数だけ行う
　-ループ処理の中で都度SQLを発行してしまっている

これにより、
Micropostテーブルに対して1回＋Userテーブルに対してMicropostの数(N) = 1回+(N)回分のSQLが発行される。

これがN+1問題。

##解決方法

ループ処理より前にuser情報を取得しておけば良い。
こんな時使うのが、**includeメソッド**

モデルA.include(:モデルB) としておくとAに基づくBを取得できる


つまり、①の部分を①'に変更する

```app/controllers/micropost_controller.rb
class MicropostsController < ApplicationController
  def index
    @microposts = Micropost.all.includes(:user) 　①'
  end
end
```
こうしておけば、 SQLは2回発行されるだけで済む。

###補足メモ

上の例ような簡単な場合はすぐにどこでN+1問題が発生しているかわかるが、もっと複雑になってきた場合、いちいちlogを見るのは大変。

こんなとき、便利なのが**「bullet」**というgem。
これを導入すると、N+1問題が発生しているページにアクセスすると、N+１が発生していることを教えてくれる。
そしてなんと解決策も一緒に教えてくれる！
便利すぎる！
Vue.js+Vuetify.jsを使ったWEBアプリケーション構築

# はじめに
この度、Vue.jsを使ってWebアプリケーションを構築しました。jQuery世代の筆者でしたが、jQuery使わずにこんなにリッチなアプリケーションを簡単に作れるのかと、改めて技術は進歩していると実感しました。
少しでも世の中のお役に立てばと思い、このアプリケーション開発で学んだVue.jsに関するノウハウを共有したいと思います。

Vue.jsとVuetify.jsを使って、サンプルアプリケ―ションを作成しましたので、今回はVue.jsとVutify.jsでどのようなアプリケーションを作成できるのか興味を持って頂ければと思います。
次回以降の投稿で苦労したことなどのポイントをサンプルアプリケーションを利用して説明する予定です。

VueやVuetifyの基本的なところは日本語マニュアルが充実しているので、公式サイトや他のサイトを参考にしてください。

以下にサンプルアプリケーションの特徴、主な動作環境及び起動手順について説明します。

# サンプルアプリケーションの特徴
- SPA（シングルページアプリケーション）
- 多言語対応
- マルチブラウザ対応

# 主な動作環境
| ライブラリ等 | バージョン |
|:-----------|:------------:|
|node.js|12.4.0|
|vue|2.6.10|
|vuetify|1.5.16|
|vue-router|3.1.3|
|vuex|3.1.1|
|vue-i18n|8.12.0|
|vee-validate|3.0.11|
|axios|0.19.0|

# 起動手順
### 1. node.jsのインストール
下記のサイトよりインストーラーをダウンロードし、インストールします。
詳細なインストール方法は割愛します。
[Node.jsダウンロードサイト](https://nodejs.org/ja/download/)

### 2. ソースコードをダウンロード
git cloneコマンドなどでサンプルアプリケーションのソースコードを取得します。

```
$ git clone https://github.com/Piecemeal-Technology-Inc/vue-app-sample.git
```
### 3. アプリケーションの初期化
取得したソースコードのルートディレクトリに移動して以下のコマンドを実行します。

```
$ npm install
```

### 4. アプリケーション起動
以下のコマンドを実行します。

```
$ npm run serve
```
以下のように出力されれば、起動完了です。

```
 DONE  Compiled successfully in 47460ms 18:54:29

  App running at:
  - Local:   http://localhost:8080/
  - Network: http://localhost:8080/

  Note that the development build is not optimized.
  To create a production build, run npm run build.
```

http://localhost:8080
にブラウザでアクセスすると以下のような画面が表示されます。
![sample1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/517349/27aca39b-c676-da8a-3982-337264810b7d.png)

#今後の投稿予定
- SPA（シングルページアプリケーション）
    - サンプルアプリケーションの構成
    - 画面遷移(Vue Router)を設定する
    - 開発環境構築が不要なアプリケーションのモックアップを作成する
- 多言語対応
    - 多言語対応（Vue I18n)を設定する
    - 入力値検証ライブラリ（VeeValidate）を多言語化する
- マルチブラウザ対応
    - Vuetify.jsでIE11に対応する
- その他
    - Vue-routerによる画面遷移で画面の入力値をそのままにする
    - 画面遷移時にアニメーションを利用する
    - Jestを利用した単体テスト
        - Jestの設定
        - Vueのライフサイクルフックをテストする
        - Jestのモック機能を利用する
        - 単体テストでc0,c1のテストカバレッジを取ってレポートを出力する
ディジタルデータとアナログデータ

現在勉強している基本情報技術者試験についてまとめたものです。
自分のアウトプット用なので見やすさなどは期待しないでください。

# ビットとバイト
**バイト**
8ビットを1とした単位。
末尾に小文字のbが書いてある場合はビット、大文字のBが書いてある場合はバイトを示す。
1バイトで表せる数は$2^8$で255通りあり、負の数も含めると0~127と-1~-128に分けられる。

**補助単位**
大きすぎたり小さすぎたりする数値を表すときに使う単位。

記憶容量などの大きい数値を表す補助単位

|補助単位|意味|
|:-:|:-:|
|キロ(k)|$10^3$|
|メガ(M)|$10^6$|
|ギガ(G)|$10^9$|
|テラ(T)|10¹²|

処理速度など小さい数値を表す補助単位

|補助単位|意味|
|:-:|:-:|
|ミリ(m)|$10⁻³$|
|マイクロ(μ)|$10⁻⁶$|
|ナノ(n)|$10⁻⁹$|
|ピコ(p)|$10⁻¹²$|

# 文字の表現方法
**文字コード**
文字に数値を割り当てたもの。
コンピューターは文字の意味など理解しておらず、この割り当てられた数値のみで判断している。
代表的な文字コードは以下のようなものがある。

**ASCll（アスキー）**
米国規格協会(ANSI)によって定められた、かなり基本的な文字コード。
含まれる文字はアルファベット、数字、いくつかの記号のみで、1文字を7ビットで表す。

**EBCDIC（エビシディック）**
IBM社が定めた文字コードで、8ビットを使って1文字を表す。
大型の汎用コンピューターなどで使われる。

**シフトJISコード(S-JIS)**
ASCllのコード体系の文字と混在させて使えるようになっている日本語文字コードで、ひらがな、カタカナ、漢字などが使える。
Windowsでも使われており、1文字を2バイトで表す。

**EUC（イーユーシー）**
拡張UNIXコードとも呼ばれ、UNIX上でよく使われる日本語文字コード。
基本的には1文字を2バイトで表すが、補助漢字などでは3バイト使う。

**Unicode（ユニコード）**
各国のありとあらゆる文字を1つのコード体系で表そうとした文字コード。
当初は1文字を2バイトで表す予定だったが、それでは足りずどんどん拡張されている。

# マルチメディアデータの表現方法
写真や音声、動画などはいずれも連続した区切りのないアナログ情報なので、コンピューターで扱うには情報に区切りを持たせ、数値で表現できるようにする必要がある。

**ビットマップ方式**
コンピューターの扱う、代表的な画像データの表し方で、画像を細かいドットの集まりで表現する。

例えば、$640 × 480$ドットの場合、合計で307,200ドットとなる。
更に、1色につき1ビットの色情報がドットごとに加わり、フルカラーだと24ビット($2²⁴ = 16,777,216$)必要になる。
これらをかけると、その画像のデータサイズを求めることができる。

**PCM(Pulse Code Modulation)**
音声データのアナログ波形データをディジタル化する代表的な手法。
音声を微小な時間単位に区切り、その単位ごととの音程を数値化することで表現する。

**標本化（サンプリング）**
アナログデータを一定の時間単位で区切り、その時間ごとの信号レベルを抽出する処理（波形の横軸）。
どのような間隔で抽出するかをサンプリング周波数といい、1秒間に何回抽出するかを「Hz」で表す。
また、サンプリング周波数1つ分の間隔をサンプリング周期という。

**量子化**
信号レベルを何段階で表現するか定め、サンプリングしたデータをその段階数に当てはめて整数値に置き換える処理（波形の縦軸）。

**量子化ビット数**
量子化の段階数を表すビット数。

# アナログデータのコンピューター制御
機器の制御は、下記の3つがセットとなって実現される。

センサ　→　コンピューター　→　アクチュエータ
　　（A/D変換）　　　　（D/A変換）

**センサ**
熱や光をはじめとする自然界の様々な情報を量として捉え、電気信号に変換する装置。

**アクチュエータ**
モーターた電磁石などを利用して、入力信号を直接信号や回転運動などの機械エネルギーに変換し、実際に動かす駆動装置。

**シーケンス制御**
あらかじめ定められた順序や条件に従って、制御の各段階を逐次進めていく制御装置。例えば洗濯機など。

**フィードバック制御**
現在の状態を定期的に測定し、目標値とのズレを入力側に戻して反映させることで、出力結果を目標値と一致させようとする制御方式。例えばエアコンなど。
getElementsByClassName()で取得した要素を配列のように扱う方法

# 問題
getElementsByClassName()はHTMLCollection()が返却されるので`forEach()`が使えませんでした。

```js

const elements = document.getElementsByClassName('xxx');
console.log(elements) //HTMLCollection()

elements.forEach((e) => {}) // TypeError: elements.forEach is not a function
```

# 解決法
HTMLCollection()をなんとか配列にしてやればOKです。

## Array.form()

```js

const elements = Array.from(document.getElementsByClassName('xxx'));
console.log(elements) //[]

elements.forEach((e) => {}) // OK
```

## [].slice.call()
```js

const elements = [].slice.call(document.getElementsByClassName('xxx'));
console.log(elements) //[]

elements.forEach((e) => {}) // OK
```
DjangoでcookieのSame-Site属性設定

#背景

2020年2月17日から、Chrome80でSame-Site属性のデフォルト値がNoneからLaxに変更されるということを知らずに生きてきたら、運用サイトで問題が起きて焦りました。
そこで、DjangoでのcookieにSame-Site属性を設定する方法を探っていたところ、Django2と3でも設定の違いがあったので、メモとして残しておきたいと思います。

#Django2の場合

###パッケージ使用の場合

簡単なのは、パッケージを使用する方法です。
自分のところはまだDjango2を使用していて、`django-cookies-samesite` というパッケージが便利そうだったので、これを使用してSame-Site属性を設定するようにしました。
https://pypi.org/project/django-cookies-samesite/

設定方法は簡単で、MIDDLEWARE_CLASSESへの追加と、設定ファイルに変数を定義するだけです。

```python
MIDDLEWARE_CLASSES = (
    'django_cookies_samesite.middleware.CookiesSameSite',
    ...
)
```

```python
SESSION_COOKIE_SAMESITE = 'None'
```

また、cookie名の設定や強制的に全cookieのSAMESITEを書き換えるオプションも付いているので、便利です。

#自分でsamesiteを追加する

自分で追加する場合は、このような形になります。これも簡単ですが、色々なところでcookieを設定している場合には少し面倒かなというところがあります。

```python
response = HttpResponse('OK')
response.cookies[key]['samesite'] = 'None'
```

#Django3の場合

Django3では既存のset_cookieが改善されて、samesiteを渡すことが出来るようになりました。これで大分すっきりしましたね。

```python
response = HttpResponse('OK')
response.set_cookie(key, value, secure=True, samesite='None')
```

ただし、Django2のようにMiddlewareでの処理ではない為、一つ一つ設定していかないと行けない点は面倒かもしれません。

#終わり

あまりchromeを閉じる習慣がない為、自分の環境ではこの問題になかなか気付かずに大変でしたが、修正自体は割と簡単なもので良かったです。
Pythonでスプレッドシートにデータを挿入するまで

google spreadsheetをpythonから操作したかったので、googleの認証とセルへの追加までの手順をまとめました。

# サービスアカウントを作成
google apisのサービスアカウントを下記のURLにしたかって作成します。
[サービスアカウントで認証してGoogleSpreadsheetからデータを取得](https://dream-yt.github.io/post/spreadsheet-via-service-account/)

# モジュールをインストール
google apiの認証とスプレッドシートの操作をするためのモジュール`oauth2client`と`gspread`をインストールします。

```bash
$ pip3 install oauth2client
$ pip3 install gspread
```

# 認証用クラス作成
複数のクラスから使えるように共通部分のクラスを作成します。

```python:google_service_account.py
import gspread
from oauth2client.service_account import ServiceAccountCredentials

scope = ['https://spreadsheets.google.com/feeds',
         'https://www.googleapis.com/auth/drive']

credentials = ServiceAccountCredentials.from_json_keyfile_name('path/to/google-service-account.json'), scope)
client = gspread.authorize(credentials)
```

# スプレッドシート挿入関数を作成
```python:google_spreadsheet_service.py
from datetime import date
from google_service_account import client

class GoogleSpreadsheetService:
    @classmethod
    def edit_cells(self):
        spreadsheet = client.open('sample') # 操作したいスプレッドシートの名前を指定する
        worksheet = spreadsheet.worksheet('Annual bonuses') # シートを指定する
        data = ['{0:%Y-%m-%d}'.format(date.today()), Hello, World] # 挿入したいデータ
        worksheet.append_row(data) # dataを最終行に挿入
```

あとは挿入したい時に`GoogleSpreadsheetService.edit_cells()`を呼びだけばOKです。

# おまけ
日付として扱われるようにDateフォーマットに合わせて整形しましたが、挿入された日付のデータはただの文字列として扱われてしまいました。

```python:before
data = ['{0:%Y-%m-%d}'.format(date.today()), Hello, World]
worksheet.append_row(data) # ただの文字列として扱われてしまう
```

`value_input_option='USER_ENTERED'`を指定することで回避できました。

```python:after
data = ['{0:%Y-%m-%d}'.format(date.today()), Hello, World]
worksheet.append_row(data, value_input_option='USER_ENTERED')
```
Raspberry Pi 4の初期設定からROSの環境構築まで

# 概要
- Raspberry Pi 4
- Ubuntu Server 18.04 LTS
- Ubuntu Mate Desktop (lightdm)
- ROS Melodic

# Ubuntu serverの初期設定
- Ubuntu server 18を起動
    - 初期アカウントのuserはubuntu、パスワードもubuntu
- wifiに接続
    - http://asukiaaa.blogspot.com/2019/10/raspberry-pi-3b64bitubuntuwifi.html

### wifiの接続が切れたとき
https://mongonta.com/f347-howto-setup-ipaddress-on-ubuntu-server-and-core/
以下のコマンドでwifi接続をし直す

```console
$ sudo netplan apply
```

# Ubuntu serverにデスクトップ環境を入れる
- https://raspida.com/ubuntumate-on-rpi4b
- https://www.hiroom2.com/2018/05/06/ubuntu-1804-mate-ja/

# リモート接続できるようにする
- 今のところできない。。。

# ROS Melodicのインストール
- https://raspimouse-sim-tutorial.gitbook.io/project/setup/how_to_install_ros_melodic

# ROS Melodicでdynamixelを制御する
- http://emanual.robotis.com/docs/en/software/dynamixel/dynamixel_workbench/#position-controller
arp-scanでmacアドレスのunknownを解消

# 目的
arp-scanでmacアドレスのunknownを解消したいとか、あるアドレスだけ特定の名前をつけて分かるようにしておきたいとかそんな目的です。

# やること
`/usr/local/share/arp-scan/mac-vendor.txt`に書き込むだけ。(ubuntu18.04の場合)

他のunix系OSならディレクトリ構成はわかりませんが、
大体似たような場所に`mac-vendor.txt`があると思うので探して書き込みましょう。


中を見ると

```
# <MAC-Prefix><TAB><Vendor>
#
# Where <MAC-Prefix> is the prefix of the MAC address in hex, and <Vendor>
# is the name of the vendor.  The prefix can be of any length from two hex
# digits (one octet) to twelve hex digits (six octets, the entire Ethernet
# hardware address).
#
# For example:
#
# 012345	would match 01:23:45:xx:xx:xx, where xx represents any value;
# 0123456	would match 01:23:45:6x:xx:xx; and
# 01234567	would match 01:23:45:67:xx:xx.
```

と書いてあるのでその通りに書きましょう。
macアドレスはベンダーを検索するサイトがあって、ググるとたくさん出てきます。
ReactでDrawerをイベント処理と表示のcomponentを分けて制作

Drawerを作るときに考えられる要素としては下記になります。

- Drawerを開くときのボタン
- Drawerを閉じるときのDrawerの中のボタン
- Drawerの中身
- containerの上に重なるalphaかかったが黒レイヤー

この要素のなかで、Drawerが開いているかどうかを判定する処理と開閉する際のイベント処理をするComponentと、Drawerの中身をただ愚直に書くだけのcomponentとを分けたいと思います。そのほうがコードの見通しがよくなると思うので。

## 書いてみた

- Material-uiを使用

### Sanple.tsx(Drawerトリガーのボタン)

- Drawerを開く処理を行うボタンを配置
- reducerを通してDrawerを開く

```javascript:Sample.tsx
<Button
  variant="contained"
  color="primary"
  type="button"
  onClick={sideMenu(true)}>
  Drawer
</Button>
<DrawerWrapper component={<Drawer />} />
```

### イベント処理をするComponent

- propsのcomponentはDrawerの中身をただ愚直に書くだけのcomponent。そのcomponentにReact.cloneElementでDrawerを閉じるevent処理と開閉判定のbooleanをpropsとして渡しています
- 開閉判定はreducerから取得しています

```javascript:DrawerWrapper.tsx
export interface ImplProps {
  closeSideMenu?: () => void;
  isSideMenu?: boolean;
}

interface ImplInnerProps {
  sideMenuAction: (arg1: boolean) => void;
  isSideMenu: boolean;
}

interface ImplOuterProps {
  component: ReactElement;
}

export type TypeDrawerWrapper = ImplInnerProps & ImplOuterProps;

const DrawerWrapper: FC<TypeDrawerWrapper> = props => {
  const { component, isSideMenu, sideMenuAction } = props;
  const closeSideMenu = useCallback(() => {
    sideMenuAction(false);
  }, [sideMenuAction]);
  return React.cloneElement(component, { isSideMenu, closeSideMenu });
};

const mapStateToProps = (state: ImplState) => ({
  isSideMenu: state.animatio.isSideMenu
});

const enhance = compose<TypeDrawerWrapper, ImplOuterProps>(
  connect(mapStateToProps, {
    sideMenuAction,
  })
);

const Drawer = enhance(DrawerWrapper);
export default Drawer;
```

composeの型定義は下記

```
compose<propsで設定したcomponentのprops, このcomponent自体のprops>
```

### 中身をコーディングするComponent

- propsは`DrawerWrapper.tsx`のReact.cloneElementで設定したpropsです
- その取得したpropsを元に表示画面を制作してます
- 背景をClickするとDrawerが閉じます
- CloseボタンをClickするとDrawerが閉じます

```javascript:Drawer.tsx
const Drawer: FC<ImplProps> = props => {
  const { isSideMenu, closeSideMenu } = props;
  return (
    <div>
      <DrawerBg onClick={closeSideMenu} isSideMenu={isSideMenu} />
      <DrawerInner isSideMenu={isSideMenu}>
        <Button
          variant="outlined"
          color="secondary"
          type="button"
          onClick={closeSideMenu}>
          Close
        </Button>
        <ul>
          <li>犬</li>
          <li>猫</li>
          <li>鳥</li>
        </ul>
      </DrawerInner>
    </div>
  );
};

export default Drawer;
```

以上になります。
event処理とReducerからstateを取得する処理のcomponentと、画面表示だけのcomponentを分けて制作してみました。
axiosを使い、APIからデータを取得する

## 概要
Reactにaxios導入し、[UnsplashAPI](https://unsplash.com/developers)からデータを取得しました。

### axiosとは？
>Promise based HTTP client for the browser and node.js

ブラウザもしくはnode.js上で動く[Promise](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Promise)ベースのHTTPクライアントです。
> Promise オブジェクトは非同期処理の最終的な完了処理（もしくは失敗）およびその結果の値を表現します。

### メリット
[fetchAPI](https://developer.mozilla.org/ja/docs/Web/API/Fetch_API) より使い方が簡単

## HTTPメソッド(CRUD)
- Create → POST/PUT

```
axios.post(url[, data[, config]])
axios.put(url[, data[, config]])
```
- Read →  GET

```
axios.get(url[, config])
```
- Update →  PUT

```
axios.put(url[, data[, config]])
```
- Delete →  DELETE

```
axios.delete(url[, config])
```

- それ以外のhead、opitonsなど使用頻度低いメソッドはここで割愛します

## 導入：React + UnsplashAPI + axios

1. axiosをインストールする
`$ npm install axios`

1. [UnsplashAPI](https://unsplash.com/developers)にてアカウントを作成し、新しいappを作成し、Documentationを参考し、アクセスキーを取得する（API認証で使われるため）　参考：[Using the Unsplash API](https://www.pluralsight.com/guides/using-the-unsplash-api)

1. GETメソッドを使い、UnsplashAPIの写真データを取得する


```react
axios.get('https://api.unsplash.com/search/photos', {
      params: {
        query: term　//ゲットしたいもの
      },
      headers: {
        Authorization: 'Client-ID YOUR_ACCESS_KEY' //UnsplashAPIのアクセスキーを置き換え
      }
    });
  }
```

1.Reactのprojectに導入し、クエリパラメータを’apple’を設定し、りんごの写真をゲットする
` $ create-react-app my-app`

```react:App.js

import React from 'react';
import axios from 'axios';

class App extends React.Component {
  state = { images: [] }

  onSearchSumbit = async () => {
    const response = await axios.get('https://api.unsplash.com/search/photos', {
      params: {
        query: 'apple'
      },
      headers: {
        Authorization: 'Client-ID YOUR_ACCESS_KEY' //UnsplashAPIのアクセスキーを置き換え
      }
    });
    this.setState({ images: response.data.results });
  }

  componentDidMount(){
    this.onSearchSumbit();
  }

  render() {
    return (
      <div className="ui container" style={{marginTop: '10px'}}>
        GETしたデータの件数：{this.state.images.length}
        {this.state.images.map((image) => {
          return <img src={image.urls.regular} />;
        })}
      </div>
    );
  }
}

export default App;
```

## 結果
<img width="1280" alt="Screen Shot 2020-03-13 at 16.22.17.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419712/afa522a1-f545-97a0-c581-2a074d16c8be.png">

---
![localhost_3000_ (1).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/419712/112637ac-61c7-b1a7-1581-f24e95c0b324.png)





## 参考
- [axiosのGitHub](https://github.com/axios/axios)
- [Udemy: Modern React with Redux](https://www.udemy.com/course/react-redux/)
Jupyter上での画像表示方法を理解する（OpenCVのimshow/matplotlibの活用）

#はじめに

　この記事では、Jupyter上で画像を表示させる方法及び、引数やリストを変えて出力画像と対応している機能を理解しようとする記事です。
　小職は機械学習初学者ですので、ご意見・間違いあればご指摘頂けると大変幸甚です。

要約

+ 画像をインライン表示させる
+ resizeモジュールを使ってモザイクをかける
+ 透過率を上げる


##画像をインライン表示させる


```python:pic.ipynb

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('012.JPG') #読み込みたい任意の画像をpic.ipynbと同フォルダに入れておきましょう。
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(1,1,1)
ax.imshow(img)
ax.axis("off")

```

![012.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/dc1d333f-78ed-1801-37a7-e4938a94ed91.png)

まずはベーシックに画像を表示させました。
ここで、(-0.5,719.5,719.5,-0.5)とは、左下の座標が(-0.5,719.5)で、右上の座標が(719.5, -0.5)であることを示しています。
画像の表示は数学で習うｘｙ軸方向と異なっており、左上に原点が来ているので、下記のようになります。

![014.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/1a39a6d3-c02d-6f45-7e51-5e99c2a96cad.png)




###画像のサイズを確認

```python:pic.ipynb
img.shape
```

```
(720, 720, 3)
```

（縦解像度、横解像度、チャンネル数）を表しますので、720×720の3チャンネル（＝RGBのカラー）ということが分かりますね。
　**注意ポイントとしては、これをｘｙで表すと（ｙ、ｘ、チャンネル数）となることです。**

　
###画像の座標及びその位置の画像を表示


```python:pic.ipynb
img[0,0]
```

```
array([162, 127,  77], dtype=uint8)
```
　原点位置(0,0)のRGB値は（162,127,77)であることが分かりました。さらに、表示を行うと以下のようになります。


```python:pic.ipynb

fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
ax.imshow(img[0:1,0:1])#表示し値座標を範囲で指定する
ax.axis("on")
```
![015.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/4cd5f71b-7792-75a0-0a39-25e50b81908d.png)

(0,0)座標を表示したい場合でも、[0:1,0:1]のように範囲で指定しなければエラーが出てしまいますので、注意しましょう。

###ｘ、ｙ座標に注意して表示する

```python:pic.ipynb
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(111)
ax.imshow(img[0:720,0:10])
ax.axis("on")
```

img[0:720,0:10]と指定すると、ｙ:0~720、ｘ:0~10で表示するため、縦長になります。ｘ、ｙ座標の頭があると逆になりますので、注意しましょう。下記画像では縦長画像になっていますね。

![018.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/8ce7c73c-e866-dbfc-8773-1bd576049ffc.png)







##resizeモジュールを使ってモザイクをかける

```python:pic.ipynb
img_re= cv2.resize(img, dsize=None, fx=0.1, fy =0.1)
fig = plt.figure(figsize=(10,10))
ax = fig.add_subplot(1,1,1)
ax.imshow(img_re)
ax.axis("off")
```
　cv2.resize()モジュールにより画素数を1/10にすることで、モザイクをかけます。
　resizeにおける引数で、fx及びfyがx,yの倍率になります。今回は0.1(=10%)とすることで、画素数を1/10にしました。

![016.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/42cd4800-ffff-da8a-13c0-ec2eba8d2905.png)



##透過率を上げる

```python:pic.ipynb
fig, ax = plt.subplots(facecolor="w")
ax.imshow(img, alpha=0.5)

plt.show()
```
imshowモジュールのalphaへの引数を0~1の範囲で指定して透過率を決めることで、薄い色合いへ変化させることができます。

![017.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/567823/a0d7114d-ea92-3620-24b5-c07e3876ea0a.png)




#終わりに

　画像を取り扱って処理をしていこうと思うと、今回の操作は基本的なものです。自分自身で手を動かすことで実感を得ておくことが非常に大事だと思いました。

プログラム全文は下記に格納しています。
https://github.com/Fumio-eisan/jupyter_pic20200313
JavaとJavaScriptは

JavaとJavaScriptは○○と△△ぐらい違うというネタが好きすぎるので投稿(n番煎じ)

個人的に好きなものだけ載せてます。思いつき次第追加していくつもりです。

# メロンとメロンパンぐらい違う

有名ですけど僕はあんまりこれは違いを実感できないんじゃないかと思ってます。インドとインドネシアも似た感じ。

# グレープとグレープフルーツぐらい違う

個人的に優勝しているやつです。次の点がいいです。

- JavaScriptがJavaにあやかっているようにグレープフルーツもグレープにあやかっている
- 「Javaのスクリプト」「グレープはフルーツ」みたいな言葉遊び的要素がある
- **グレープジュースを頼んでグレープフルーツジュースが出てきたら僕なら怒る** → 違いが実感しやすいし現実生活で起こりうる

# VisualStudioとVisualStudio Codeぐらい違う

「JavaはVSではないものの統合開発環境があったほうがよく、JSはVSCodeで十分」みたいな感じで対称性がよく出ているように思えます。

# GitとGitHubぐらい違う

逆に「GitとGitHubはJavaとJavaScriptぐらい(それ以上?)違うよ」って教えてあげるといいかもしれません。

# Minecraft Java EditionとMinecraft Pocket Editionぐらい違う

Java版のmodはJavaで、PE版のmodはJavaScriptで作成されるのでちょうど良い対称になっています。

# 電気通信大学と電通と大阪電気通信大学と東京通信大学と東京電機大学ぐらい違う

ごっちゃにしていた人は反省してください。電気通信大学はこの中で唯一国立(くにたち)の近くにある国立(こくりつ)の大学です。

# 大学と大学院ぐらい違う

大学院進学のための奨学金制度、大学より乏しいですよね。ケチ。

# .NET Frameworkと.NET Coreぐらい違う

これで半日潰しました

# そばと焼きそばぐらい違う

この例えだとTypeScriptがかた焼きそばになるのでその点は好きです。
Pythonで毎日AtCoder #4

### はじめに
[前回](https://qiita.com/taxfree_python/items/83862d846fa90e7abdd8)
4日目です。

### #4
[問題](https://atcoder.jp/contests/abc033/tasks/abc033_b)
わーい。B問題だー

**考えたこと**
入力される[町の名前、人口]を人口でsortして、一番大きい町が過半数以上あるか判別します。
私の場合は、[町の名前、人口]みたいに二次元配列なので普通にsortできないので、

```python
s.sort(key=lambda x: int(x[1]),reverse=True)
```
でsortしました。[参考にしたページ](https://note.nkmk.me/python-list-2d-sort/)
おしゃれでかっこいいので好き。x: int(x[n])で要素のindexを指定してsortできます。今回は人口でsortしたいのでx[1]、大きい順にしたいのでreverse=True。

人口はfor文で計算しました。

```python
population = 0
for i in range(n):
    population += int(s[i][1])
```
ちゃんと変数名を分かりやすく書きました。少し長いけど。
あとはif文に入れるだけ。

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

population = 0
for i in range(n):
    population += int(s[i][1])

s.sort(key=lambda x: int(x[1]),reverse=True)

if int(s[0][1]) > population//2:
    print(s[0][0])
else:
    print('atcoder')
```
最後に、print('atcoder')のスペルミスに気をつければ大丈夫。

### まとめ
B問題でも簡単な方だと思います。明日は、コンテストがあるので投稿するか迷ってます。~~毎日投稿~~
では、また
【Nuxt.js】Scssを使う方法 

###ScssをNuxt.jsで使おうとおもったら

```
NuxtServerError
Cannot find module './index.vue?vue&type=style&index=0&lang=sass&'
```

こんなエラーが出て、使えませんでした。
「そんなの知らねーよ」 って感じのエラーです。

**そう、ライブラリを入れなきゃ使えないのです。**

検索して、シンプルな記事が見つけられなかったので、サクッと書きます。
すぐ終わります。

##環境
@nuxt/cli v2.11.0


##やり方
３つのライブラリを入れるだけ。
node-sass
sass-loader
style-loader

下記コマンドでOK。

```ターミナル.
npm install node-sass sass-loader style-loader
```


これで、NuxtでScssが使えるようになります。


具体的な使い方はこちら。
**styleタグの中にlang="scss"を入れます。**

```index.vue
<template>
  <div class="Main">
    <h1>GEEK</h1>
  </div>
</template>

<script>
export default {};
</script>


<style lang="scss"> //lang="scss"を忘れずに
.Main {
  height: 600px;
     h1 {
         font-size: 50px;
     }
}
</style>

```

ちゃんとScssが動き、
.Mainにネストされてるh1の文字が変化します。

コンパイルは、Vue(Nuxt)側でよしなにやってくれるので不要です。

3つのライブラリが何をしてるか気になる人はぜひ調べてみてください。
node-sass
sass-loader
style-loader

お疲れ様でした。
blocklyでobjectを動かす。

#概要

blocklyでobjectを動かして見る。

#ステージを作る。

今回は、テキストエリア。

```
<textarea rows="15" cols="50" id="out"></textarea>
```

#フローを書く。

九九を書いてみる。

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/7fb8379d-6d1d-94fe-b800-dc535de4a2e4.png)


#objectを書く。

今回は、printをオーバーライドする。

```
Blockly.JavaScript.text_print = function(a) {
    return "document.getElementById('out').value += " + (Blockly.JavaScript.valueToCode(a, "TEXT", Blockly.JavaScript.ORDER_NONE) || "''") + "\n"
};
```

#結果

![image](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/a48823ea-7be1-cd65-e80e-eeb61350b7c4.png)

#成果物

https://embed.plnkr.co/plunk/PiAasJ2lMeF02ewr

以上。
Macボリュームの空きを占有してたのはローカルのタイムマシーンデータだった・・・

macの空き容量がなくなってしまって作業が数日滞ってしまった。。。
・・・ってことで、セーフモードで立ち上げたり、ストレージを最適化したり、不要なファイルを削除したりしたけど、解決せず。

First Aidをやってたら、タイムマシーンのローカルスナップショットをチェックしているログが出てたので対応策をググって見つけたページがこれ↓
https://blog.h-wd.info/2018/12/19/macos-mojave-delete-localsnapshots/

３００ギガ復活しました！！！
Macのメモ（Notes.app）から全テキストを取り出す JXA

## Mac のメモアプリから全テキストを取り出す
　iPhone, iPad や Mac で使用しているメモアプリ（Notes.app）内の全てのメモからタイトルと本文（テキストの見）を取り出すJXA (JavaScript for Automation) です。
　メモに入っているノートのタイトルと本文（テキストのみ）を取り出して、テキストエディタアプリに貼り付けます。
形式はタイトルを「【」と「】」で囲み、改行して本文のテキストが続きます。
分けたい方は「【...】」で検索して分けることできるでしょう。

## ソース（JXA）
　コードは単純ですので、好きなように改変して利用してください。

```javascript:getNotes.scrpt
var app = Application.currentApplication()
app.includeStandardAdditions = true

var noteApp = Application("Notes")

noteApp.activate()
delay(2)

var folders = noteApp.folders
var results = ''
for (eachFolder in folders) {
	var notes = folders[eachFolder].notes
	for (eachNote in notes) {
 		var noteName = notes[eachNote].name()
		var noteText = notes[eachNote].plaintext()
		results = results + "\n【" + noteName + "】\n" + noteText
	}
}

var textEdit = Application("TextEdit");
textEdit.activate()	
delay(2)
var doc = textEdit.Document(); // 新規にドキュメントを作成
textEdit.documents.push(doc); //　画面に表示する
doc.text = results		// TextEdit に結果をセットする
```
Trigger Conditionsを追加してFlowの発動回数を節約する

#Trigger Conditions??
Docsだと全然情報ないのですが、各トリガー(Flowの開始部分)に追加で設定できる発動条件です。
トリガーの[・・・]をクリックして表示されるメニューでSettingsを選ぶと表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/76ba0405-01c4-efb7-5fe4-dc9b6bc1bdfb.png)
ここには、もともとのトリガーの条件とは別に、トリガーしたときのアイテムや各種データをもとに、さらに発動条件を指定することができます。
例えば、SharePointのアイテム作成トリガーで、特定のステータス(選択肢フィールドの値)の場合だったら～とか、反復実行で1分おき に設定するのだけど、発動は日中だけにしたい とか。
そういった、もとのトリガーだけではカバーしきれないようなカスタムの発動条件が定義できます。

Trigger Conditionsを使わない場合、トリガーの次のステップでIFやSWITCH等の分岐条件を入れるかと思います。Falseなら実行終了とか。
そういった「発動はさせるけど、すぐ条件で終わらせることがある」ようなFlowに対して、Trigger Conditionsは有効に働きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/ded1dd32-dde6-2c12-315f-8ddc4681fd0f.png)

## 何がうれしい？
単純にはトリガー回数を減らせるので、実行履歴が見やすくなります。あとは誤って深夜とかに発動してPush通知飛んじゃう みたいなことも避けれるかもしれません。

ただ、多少は数式を書かないといけないので、そこだけはトレードオフです。

## 何に使える？
すぐ思いついたのは以下のパターンです。
1. SharePointリスト/ライブラリで、**更新のみ**検出する (標準では作成と更新どちらも発動する)
2. リストの特定のステータスでのみ対象とする (これも作成・更新で後ろでIFしたりする)
3. 反復のスケジュール実行で、実行のウィンドウを指定する (繰り返しを1日おきで、時間指定でもいいけど短いインターバルだと結構大変)

# Trigger Conditionsの設定
簡単にいくつかのパターンでTrigger Conditionsの設定方法を見てみます。

## 1. トリガーしたときのデータに応じた条件
例として、SharePointの選択肢フィールドの値に応じた処理を考えてみます。
データに応じた処理を行う場合、基本的には ```triggerBody()``` に連なるデータを参照して、条件を書きます。

最初はどんな式を書けばいいのか、どんなデータを受信しているかわからないと思いますので、すごく短い、ただtriggerBody()をComposeするだけのFlowを作ってテストします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/6eeb0e2a-a089-f9b6-c769-0ce8b05d5b25.png)
これで得られる結果をもとにして、例えば"Title"のデータを使いたいなら 

```
triggerBody()?['Title']
``` 

を利用します。

選択肢フィールドであるStatus は階層的になっているので、その値を使うときは ```triggerBody()?['Status']?['Value']``` になります。

Trigger Conditionsで必須なのは条件式、つまり論理演算です。公式のドキュメントが一番見やすいので [こちら](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#logical-comparison-functions) をご覧ください。
あとはお約束事ですが、Trigger Conditionsの式を書くときは**先頭に @ をつけます**。

これらを踏まえて、**『Status列の値が"Closed"の場合』** というTrigger Conditionsは

```
@equals(triggerBody()?['Status']?['Value'],'Closed')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/d6417b36-639c-0e33-759f-42379ff81951.png)

このように書けます。

## 2. データ以外の情報を利用する場合
あまり思いつきませんが、指定した時間(hour)で高頻度でFlowを実行させたい場合(7:00~8:00の間に5分間隔とか)には、

```
utcNow() :　トリガーした時間 (UTC)
formatDateTime() : utcNow()から時間(hour)だけを取り出すために利用
int() : formatDateTimeの結果のStringを整数に変換 
```
これらの関数を組み合わせていきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/797a3f7d-bd0e-5c1a-970e-cb4db3555efa.png)

実際に一日ONにしてみましたが、指定時間の間だけ、5分間隔で実行されていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/e0468799-48ed-4643-f809-6cb177fc8644.png)


# おわりに
標準のトリガーで提供されている条件以上に、何かカスタマイズした条件を指定したい場合、Trigger Conditionsの利用は非常に有効です。
Flow全体をきれいに整えることにもつながりますし、個人的には実行履歴が埋め尽くされないのがメリットだと思います。

少し数式になれる必要はありますが、使いこなせればなかなか面白いので、一度試してみてください！
指定したキーは、このコンテナー内に存在しません。の対処法

MATLABの「指定したキーは、このコンテナー内に存在しません。」のエラーの日本語情報がなかったのでメモ．

引用
https://jp.mathworks.com/matlabcentral/answers/246457-why-do-i-see-the-specified-key-is-not-present-in-this-container-error-in-my-installation-log-file

サポートパッケージの再インストールか.mexファイルの削除で解決するらしい．
私の環境ではcodegenで生成された.mexファイルの削除で解決した．
MacOS brew  phpenv環境 にphpをインストールする

`phpenv install 7.4.3` で済めばよかったのだが、なかなか苦労したのでメモ

# PHP 7
```sh
PHP_BUILD_CONFIGURE_OPTS="--with-bz2=$(brew --prefix bzip2) --with-iconv=$(brew --prefix libiconv)" \
PKG_CONFIG_PATH=/usr/local/opt/krb5/lib/pkgconfig:/usr/local/opt/openssl@1.1/lib/
pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libedit/lib/pkgconfig \
phpenv install -v 7.4.3
```
+ -v オプションで ./configure のエラー出力を見ながらやると良い
+ ./configure のエラーで PKG_CONFIG_PATH の追加をすすめられたら、対応するパスを追加
+ それ以外のエラーは PHP_BUILD_CONFIGURE_OPTS で解決する
+ php-build の default_configure_options に設定を書いておけるが、バージョン毎に差がありそうなためやめておく

# PHP 5
configure は成功するもののコンパイルに失敗

```sh
PHP_BUILD_CONFIGURE_OPTS="--with-bz2=$(brew --prefix bzip2) --with-iconv=$(brew --prefix libiconv) --with-zlib=$(brew --prefix zlib) --with-curl=$(brew --prefix curl) --with-libedit=/usr/local/opt/libedit" \
PKG_CONFIG_PATH=/usr/local/opt/krb5/lib/pkgconfig:/usr/local/opt/openssl@1.1/lib/pkgconfig:/usr/local/opt/icu4c/lib/pkgconfig:/usr/local/opt/libedit/lib/pkgconfig:/usr/local/opt/curl/lib/pkgconfig \
phpenv install -v 5.6.40
```
関数とベクトル

#関数はベクトルである

ベクトルは、以下の公理を満たすものなのて、関数もベクトルだということができる。

|公理|条件|
|---|---|
|加法の結合律|$u + (v + w) = (u + v) + w$|
|加法の可換律|$u + v = v + u$|
|加法単位元の存在|零ベクトル $0 ∈ V が存在して、全ての v ∈ V において v + 0 = v を満たす。$|
|加法逆元の存在|$各ベクトル v ∈ V に、加法逆元 −v ∈ V が存在して、<BR> v + (−v) = 0 とできる。$|
|加法に対するスカラー乗法の分配律|$a(u + v) = au + av$|
|体の加法に対するスカラー乗法の分配律|$(a + b)v = av + bv$|
|体の乗法とスカラー乗法の両立条件|$a(bv) = (ab)v [nb 2]$|
|スカラー乗法の単位元の存在|$1v = v （左辺の 1 は F の乗法単位元）$|

普通のベクトル

```math
r=\left(  \begin{array}{c}x \\y\end{array}\right)
```
は、

```math
e_1=\left(  \begin{array}{c}1 \\0\end{array}\right)\\
e_2=\left(  \begin{array}{c}0 \\1\end{array}\right)

```
とう基底を使うと、
$$r=xe_1+ye_2$$
と書けます。

同様に、

$区間(a,b)で定義される関数\psi_1 (x), \psi_2 (x)が，正規直交基底 \\{ \phi_i (x) \\}の線形結合で表されるていると、$

```math
\psi_1(x)=\sum_{i=1}^{\infty}\alpha_i\phi_i(x)\\
\psi_2(x)=\sum_{i=1}^{\infty}\beta_i\phi_i(x)
```

このときの $\psi_1(x), \psi_2(x)$ の内積は、以下の通りとなります。

```math
\langle\psi_1(x), \psi_2(x)\rangle  = \int_a^b \psi_1^*(x)\psi_2(x)dx= (\alpha_1^*, \alpha_2^*\ldots)\left( \begin{array}{c}\beta_1 \\\beta_2\\\vdots\end{array}\right)
```

ここで、ケットベクトル $|\psi_2\rangle$を、以下のように定義すると、

```math
|\psi_2\rangle =  
\left( \begin{array}{c}\beta_1 \\\beta_2\\\vdots\end{array}\right)
```

ブラベクトル $\langle \psi_1|$を、以下のように定義すると、

```math
\langle \psi_1| = ( \alpha_1^*,\alpha_2~*,\ldots)
```
このブラベクトルは、ケットベクトルを転地して、共役を取ったもので、$\dagger$で表されます。

```math
\langle \psi_1|=|\psi_1\rangle^\dagger
```

内積は、ブラとケットを用いて、以下のように表せます。

```math
\langle\psi_1(x), \psi_2(x)\rangle = \langle \psi_1|\psi_2\rangle
```


#参考資料
[ベクトル空間](https://ja.wikipedia.org/wiki/%E3%83%99%E3%82%AF%E3%83%88%E3%83%AB%E7%A9%BA%E9%96%93)
[ベクトルと関数のおはなし](http://www.natural-science.or.jp/article/20120306220904.php)
HCL2形式ファイルでのPacker実行

# 要約

PackerをHCL2で記述してみた

# 背景

[Packer 1.5.0からHCLを対応した](https://www.hashicorp.com/blog/announcing-hashicorp-packer-1-5-with-hcl2-support/)とのことなので、使ってみた。

ここでは、以下のようにPackerを使う

# 実施内容

PackerとAnsibleを使いNginxのVMイメージ(カスタムイメージ)をGCP上で作成する。

## 詳細条件

- Packer version: 1.5.4
- ansible version: 2.9.4
- IaaS: GCP

[フォルダ構成](https://github.com/AtsushiKitano/assets/tree/master/images/gcp_custom_image/nginx_server)は、下記の通り

```
  ./
   |
   +- build.pkr.hcl
   +- locals.pkr.hcl
   +- source.pkr.hcl
   +- variables.pkr.hcl
   |
    -scripts/
         |
         - ansible-playbook.yaml
```

## 記法

- packerビルドを実行するファイルの拡張子:  `.pkr.hcl` 
- 処理のブロック: `source`, `build` , `variables` , `locals`

各ファイルの中身
 
```build.pkr.hcl
build {
  sources = [
    "source.googlecompute.nginx"
  ]
  provisioner "ansible" {
    playbook_file   = "./scripts/ansible-playbook.yaml"
    user            = "packer"
    extra_arguments = ["-vvvv"]
  }
}
```

``` source.pkr.hcl
source "googlecompute" "nginx" {
  project_id          = "ca-kitano-study-sandbox"
  source_image_family = local.img_fam
  preemptible         = true
  ssh_username        = "packer"
  zone                = "asia-northeast1-b"
  image_name          = var.image-name
  tags                = ["packer"]
}
```

```locals.pkr.hcl
locals {
  img_fam = "debian-9"
}
```

``` variables.pkr.hcl
variable "image-name" {
  type = string
  default = "nginx-demo"
}
```

Ansible Playbookは下記の通り。

```ansible-playbook.yaml
- hosts: all
  become: true
  tasks:
    - name: package repository update
      apt:
        update_cache: yes

    - name: install nginx
      apt:
        name:
          - nginx
```

## 実行方法

```bash
$packer build ./
```

実行が成功すると、GCP上に `image_name` で指定したカスタムイメージが作成される。

# まとめ

packerをhcl2形式で記載した。json形式よりも書きやすい。
TerraformでHCL形式に慣れている人は、是非使っていくとよいと思う。
【MC】各ステップをいつ実行したか確認するためのログ

https://knowledge.bizrobo.com/hc/ja/articles/360028268171-%E3%83%AD%E3%83%9C%E3%83%83%E3%83%88%E3%81%AE%E5%AE%9F%E8%A1%8C%E3%83%AD%E3%82%B0%E3%81%AE%E8%A8%AD%E5%AE%9A%E6%96%B9%E6%B3%95

上記の設定をすればOKみたい。

https://qiita.com/Mune_robo/items/742aa84908d2f9141053
のブログで出力するログに記載されている時間は
ログを記載した時間なので、いつ実行したかはわからない。
Vue Composition APIでVuexやVue Routerを扱う

## はじめに

- Vue3.0で既存のライブラリを扱う場合にどう考えればいいかという話
- VuexやVue Routerが公式にComposition APIを対応するまでの話

## setup関数でVuexにアクセスする

とりあえずサンプルです。

```vue
<script lang="ts">
import { createComponent, onBeforeMount } from '@vue/composition-api'
import { fetchActionName } from '@/store/actions'

export default createComponent({
  setup(props, context) {
    const store = context.root.$store

    onBeforeMount(async () => {
      await store.dispatch(fetchActionName)
    })

    return { state: store.state }
  }
})
</script>
```

setup関数のcontextの中にはrootというオブジェクトがあります。型定義をみるとVueのインスタンスがそのまま入っていています。

```typescript
export declare type ComponentInstance = InstanceType<VueConstructor>
```

昔からVuexなどでは `this.$store` といった形でインスタンスに生やすライブラリがありますが、そのあたりのライブラリは一旦この方法で対処できると思われます。

データの表示はsetupの返り値でVuexのstateを返すことでhtml上で表示することができました。しかし、表示を加工して返したい場合などが大半だと思うので素直にcomputedを定義した方が良いのかもなと感じています。この辺は公式が対応するまで辛そう。

APIデータ取得などのactionsは新しいライフサイクルメソッド上で扱う必要が出てきますが、基本はcreated、mounted、destroyedの範囲で実装していれば移行は問題はないと思います。

modulesを使っている場合などでアクション名が複雑化している場合や、dispatchのタイプミスが怖い人なんかはactionsの関数名をmutationsのようにVuexのファイルに近い場所に配置にして別途importしていくのが良いと思います。payloadの型定義はゆるふわになりますがそこは送る手前でオブジェクトに型定義しておけば良いと思います。

## setup関数でVue Routerにアクセスする

Vue Routerも同様の方法で取ってくることができます。

```vue
<script lang="ts">
import { createComponent } from '@vue/composition-api'

export default createComponent({
  setup(props, context) {
    const router = context.root.$router

    function move() {
      router.push({ name: 'about' })
    }

    return { move }
  }
})
</script>
```

Vuexの中にルーター情報を連携してたりしなければほとんど問題が無いと思います。
Github用にtigをAmazon Linux 2にインストールした話

AWSのEC2環境にGithub用にtigをインストールしたのでそのときの内容をまとめたいと思います

#環境
○AmazonLinux2

#インストール手順
○tigインストール用にワークフォルダを作って移動します（フォルダの作成は任意のフォルダ名でOKです）

```
$ mkdir work
$ cd work
```
○git cloneでソースコードをダウンロードしてフォルダに移動します

```
$ git clone https://github.com/jonas/tig.git
$ cd tig
```
○必要なパッケージをインストールします

```
$ sudo yum install automake
$ sudo yum provides \*/curses.h
$ yum install ncurses-devel
```
○日本語化の設定を行っていきます

```
$ ./autogen.sh
$ LDFLAGS=-L/usr/lib/ncursesw CPPFLAGS=-I/usr/include/ncursesw ./configure
```
○prefixを付けてコンパイル・インストールしていきます

```
$ make prefix=/usr/local
$ sudo make install prefix=/usr/local
```
以上で日本語対応済みのtig環境を使えます！

#参考にしたページ
　[[git] tigのインストール](https://tamulab.jp/git-install-tig/)
FlutterでVSCodeからiOSの起動ができない時

`Pod install fails on invalid byte sequence while having LANG=en_US.UTF-8 in profile`という感じのエラーが出てVSCodeでFlutterアプリが起動できないことがある。

`WARNING: CocoaPods requires your terminal to be using UTF-8 encoding.
Consider adding the following to ~/.profile:
export LANG=en_US.UTF-8`とか出てるから言われたとおりに`~/.profile`に`export LANG=en_US.UTF-8`を追記したけど、だめだった。

## 解決方法

.vscode/launch.jsonファイルを作成して、以下のようにする。

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Flutter",
            "request": "launch",
            "type": "dart",
            "env": {
                "LANG": "en_US.UTF-8"
            }
        }
    ]
}
```

`env`の指定が重要！
ターミナル操作：今いるブランチ名を表示させよう

# レクチャー動画で良く見るこれ
今いるディレクトリ横に、**現在のブランチ名が表示されてる！**
なんて便利なんだー！
これがあれば、わざわざ
`git branch`
して、確認せずに済むではないかー！

<img width="705" alt="スクリーンショット 2020-03-13 15.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/490c7728-94b3-cca6-565f-4e00bc67a518.png">


# てこでやり方をまとめてみました！！

# Mac標準のgitを使ってない？
```
which git
出力　/usr/local/bin/git
```
これ以外の出力になっていると、標準Macのgitの可能性あり。

# Homebrewでインストールできてる？
```
brew list
出力　git
```
Homebrewでインストールする最新verのgitが必要。
上記コマンドで出力されない人は、Homebrewで最新verのgitをインストールしよう！

```
git --version
出力　現在のgitのver
```
ちなみに現在2020/3/14では、git version 2.25.1でした。

# Homebrewでgitをインストール
```
brew install git
```
少し時間かかります。
この時、インストール先が表示されるので覚えておきます！
<img width="1440" alt="スクリーンショット 2020-03-13 14.15.29.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/777cc32e-bb82-7655-4656-2f5bfdc6a387.png">
**私のインストール先は、/usr/local/Cellar/git**

# PATHを通す

`sudo vi ~/.bash_profile`
ここを編集。最後の行に追加しましょう。以下を↓

```
PATH=/usr/local/Cellar/git:$PATH
export PATH
```

`source ~/.bash_profile`
ファイルの内容を更新。これをしないと反映されないです。


```
which git
出力　/usr/local/bin/git
```
**これになっているはず。**

# いよいよ仕上げ！
`sudo vi ~/.bashrc`

を開いて、ブランチ名をターミナルでも表示させる設定を記述。

```
source /usr/local/etc/bash_completion.d/git-prompt.sh
source /usr/local/etc/bash_completion.d/git-completion.bash
GIT_PS1_SHOWDIRTYSTATE=true
export PS1='\[\033[32m\]\u@\h\[\033[00m\]:\[\033[34m\]\w\[\033[31m\]$(__git_ps1)\[\033[00m\]\$ '
```

`source ~/.bashrc`
ファイル内容を更新。

<img width="705" alt="スクリーンショット 2020-03-13 15.10.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449720/490c7728-94b3-cca6-565f-4e00bc67a518.png">
こんな感じで、今いるディレクトリの横に所属しているブランチ名が表示されるはず！