OmniAICreator/Qiita-1.07M huggingface dataset:
VPC設定ついでにまとめてみた

# 概要
コンソールからVPC設定しているのでついでにVPC周辺の詳細を記述していきます。

# VPC(Virtual Private Cloud)とは
- AWSアカウント専用の仮想ネットワーク空間のこと
- 社内ユーザのみアクセスが可能な仮想ネットワークの構築が可能(インターネットからはアクセスできない)
- アカウント作成時はデフォルトでVPC(Default VPC)が１つ作成されているが、ユーザ毎に個別で作成可能

![スクリーンショット 2020-02-16 19.03.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379873/4d6ff301-3d69-2679-1278-32b3a07e7fc2.png)

## リージョン
世界22ヶ所の分散されたデータセンター群で構成されている。
日本のリージョンは現在(2020年2月時点)は東京リージョン(ap-northeast-1)のみ

**※ 大阪ローカルリージョンが2021年初頭までに3つのアベイラビリティーゾーンを持つ完全なAWSリージョンに拡大するそうです。**

## アベイラビリティーゾーン(AZ)

各リージョンに存在するデータセンタの事
VPCはAZをまたいで作成できるがリージョンはまたげない


# IPアドレスの範囲
ユーザー毎に隔離されたネットワークを作成する為には、VCP領域に対してIPアドレスの範囲を与える必要がある。

## CIDR(Classless Inter-Domain Routing)表記とは

例: 192.168.1.0〜192.168.1.255

上記のような256個のIPアドレスは通常IPアドレス範囲を表す時はサブネットマスク表記やCIDR表記を使用します。

```
サブネットマスク表記だと
192.168.1.0/255.255.255.0となり

ネットワーク部が32ビット中24ビット使用されているのでCIDR表記では
192.168.1.0/24と記述することができます。

24の部分は「プレフィックス」とも言いVPCではプレフィックスは16ビットから28ビットで構成する必要があります。
```

## CIDRと利用可能なIPアドレス数

CIDRブロックでは最初の4IPと最後の1IPは利用できない為、利用可能なIPアドレス数から-5しています。
参考: https://aws.amazon.com/jp/premiumsupport/knowledge-center/change-subnet-mask/

16ビットから28ビットのプレフィックスと利用可能なIPアドレス数を下記の表にまとめました。

|プレフィックス|利用可能なIPアドレス数|
|-------|-------|
| 16 | 65531 |
| 18 | 16379 |
| 20 | 4091 |
| 22 | 1019 |
| 24 | 251 |
| 26 |  59 |
| 28 |  11 |

```
例: プレフィックスが18の時
サブネットマスクが下記のようになり

11111111 11111111 11000000 00000000
=> (64 * 256) -5 = 16,379となる
```

# サブネット
- VPC内に構成するネットワークを分割したもので1つのVPCに対して1つ以上のサブネットで構成される。
- サブネットを分けることで仮に片方のサブネットに障害が起きても、異なるサブネットに影響が生じにくくなることやそれぞれ別のネットワークの設定ができる為セキリティを高められる。
- VPCのIPアドレスの範囲内で設定

```
例: VPC CIDRが「10.0.0.0/16」の場合
サブネットは細分化された「10.0.1.0/24」や「10.0.2.0/24」などで作成
```

## パブリックサブネット
インターネットに直接接続し外部に公開される
インターネットゲートウェイを経由させることでインターネットとの接続を可能にする

### インターネットゲートウェイ
インターネットゲートウェイをVPCにアタッチすることで、アタッチしたVPC内のサブネットがインターネットへ接続できる。

### ルートテーブル
どのネットワークに対する通信をどこのネットワークに流すかを定義するもの
ルートテーブルでデフォルトゲートウェイ(0.0.0.0/0)を設定して、インターネットゲートウェイを指定したものはパブリックサブネットになり、それ以外はプライベートサブネットになる


|destination(送信先)|target|
|-------|-------|
|10.0.0.0/16|local|
|0.0.0.0/0|インターネットゲートウェイ|

## プライベートサブネット
DBサーバーなどバック部分はインターネットに接続されたくない事やセキュリティーを高める必要があるので、プライベートサブネットでサーバーを隠す
サーバーからインタネットに接続することもできなくなるのでソフトのインストールやアップデート(yumの実行など)を可能にするにはNATを使用する

### NATゲートウェイ
NATはIPアドレスの置換を行う(送信元のプライベートIPアドレスをNAT上のパブリックIPアドレスに置換する)事でプライベートサブネットからインターネットへ接続が可能にする
インターネットからプライベートサブネットへの接続はできない

ちなみにIPアドレスとポート番号を置換する事で複数のホストを共有可能にしたものはNAPTという

![スクリーンショット 2020-02-16 0.49.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/379873/e237db7f-092d-b50b-119a-ff41d01c04a5.png)


NATを使用する為にNATゲートウェイ設置する必要があるが、作成時にはインターネット接続可能なパブリックサブネットとEIPを割り当てる必要がある

### EIP(Elastic IP)
パブリックIPアドレスは起動/停止するたびに別のIPアドレスに割り当てられるのでEIPでIPアドレスを固定する
インスタンスにアタッチされている時は料金は発生しないが、どのインスタンスにもアタッチされていない場合は1時間当たり約0.5円の料金がかる

公式(オンデマンド料金): https://aws.amazon.com/jp/ec2/pricing/on-demand/

## セキュリティーグループとネットワークACL

| ファイアウォール| 範囲|初期インバウンド|初期アウトバウンド | ルール|
|-------|-------|-------|-------|-------|
|セキュリテイーグループ|EC2インスタンス毎|全て拒否|全て許可|累積的に許可|
|ネットワークACL|サブネット毎| 全て許可|全て許可|マッチした時点で許可、以降は拒否|


# 最後に
今回はVPCを中心に内容を記述していきましたが、今回書いていないVPC周辺の知識やコンソール上では理解しにくいAWSの他のサービスの知識があるので設定しながらまたまとめていけたらなと思います。
標準入力でCSVをPHPに渡し配列にする

#やること
csvをshellスクリプトで標準入力し、phpファイルで加工する

#コード
```
<?php
while ($row = fgetcsv(STDIN)) {
    var_dump($row);
}
```

```
$ php [ファイル名].php <　[ファイル名].csv
```
これでcsvを成形しやすくなります

#まとめ
1つのファイルを加工するのであればとても便利でした。
2つ以上のファイルを加工するのであればまた違う方法が必要なのかなと思いました。
またコマンドラインで渡すことができたら使い回しが簡単になったのでshellも便利だなと感じました。

#参考
[PHPでコマンドラインの入力をする](https://junpeko.com/stdin/)
[PHPで標準入力を取得する方法](https://suin.io/511)
[PHPでCSVを配列にする](https://qiita.com/863/items/3c87752eadb8e6877d51)

#追記
@tadsan さん
コメントでの指摘ありがとうございます。
より簡単なコードを書けて勉強になりました。
スクロールすると要素が揺れるページを作る

最初はJSのみで実装しようと思いましたが、難しくて挫折。CSSアニメーションを使えばかなり簡単に作れましたー。ちなみに、ライブラリは使っていません。

何かしら良さげなライブラリがありそうですが、パッと見た感じなさそうなので作ってみました。

HTMLは必要最低限。

HTML

```html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>trace huuuu</title>
  <link rel="stylesheet" href="style.css">
</head>
<body style="height: 200vh; width: 100vw;">
  <div class="shakes"></div>
  <div class="shakes"></div>
  <div class="shakes"></div>
  <div class="shakes"></div>
  <div class="shakes"></div>
  <div class="shakes"></div>
  <script src="script.js"></script>
</body>
</html>
```

揺らす要素にshakesというクラスを付けています。
`transform-origin: 50% 0;`と書いておくと、揺れてる感が出て良き良き。

CSS

```css
.shakes {
  width: 200px;
  height: 100px;
  margin: 150px;
  transform-origin: 50% 0;
  background-color: pink;
}
```

正直JSはコードに自信がないので晒したくはないのですが、ひとまず下記のような感じにしてみました。

各要素ごとに、振幅にばらつきがあったり、振れの速度が違った方が面白いので、それぞれランダムな値を持たせています。

JavaScript

```js
let oldPos = 0;
let timeoutId = 0;
let scrolls = [];
let minShakeAngle = 0.3; // 最小振れ角
let attenuation = 0.8; // 振幅減衰率
let defaultAngle = 45; // 基準振れ角

window.onload = () => {
  oldPos = window.scrollY;
  let shakes = Array.from(document.getElementsByClassName('shakes'));
  shakes.forEach((shake, index) => {
    scrolls.push(new Scroll(shake));
  });
  
  window.addEventListener( "scroll", () => {
    clearTimeout( timeoutId );
    let timeoutId = setTimeout( function () {
      let distance = Math.abs(window.scrollY - oldPos);
      let angleRate = distance / (document.body.clientHeight - window.innerHeight);
      let angle = angleRate * defaultAngle;
      scrolls.forEach((scroll) => {
        scroll.shakeSet(angle);
      });
      oldPos = window.scrollY;
    }, 15);
  });
}

class Scroll {
  constructor(el) {
    this.el = el; // 要素
    this.currentAngle = 0; // 現在の振れ角
    this.add = 1; // 振れ方向の正負
    this.animationId;
    this.animateFlg = false; // 振れているかどうか
    this.angleRate = Math.random() + 0.5; // 要素ごとの振れ角のばらつき
    this.animationInterval = 200 * Math.random() + 500; // 要素ごとの振れ速度
    // 要素ごとに振れ速度を変えて、
    el.style.transition = `transform ${this.animationInterval}ms ease-in-out`;
    // インスタンス生成時に要素を揺らしています。
    this.shakeSet(10);
  }

  shakeSet(angle) {
    angle *= this.angleRate;
    if(this.currentAngle < angle) {
      this.currentAngle = angle;
      if(!this.animateFlg) {
        this.animateFlg = true;
        this._shake();
      }
    }
  }

  _shake() {
    this.animationId = setInterval(() => {
      this.el.style.transform = `rotate(${this.currentAngle * this.add}deg)`;
      this.add = this.add * -1;
      if(this.currentAngle < minShakeAngle) {
        this.el.style.transform = `rotate(0deg)`;
        clearInterval(this.animationId);
        this._clearVariable();
        return;
      }
      this.currentAngle *= attenuation;
    }, this.animationInterval);
  }

  _clearVariable() {
    this.add = 1;
    this.currentAngle = 0;
    this.animateFlg = false;
  }
}
```

動作は下記URLより

https://mi-miya.github.io/traces/huuuu/
投稿された住所をマップに反映させるRailsアプリを作る

Railsで、ユーザが投稿した住所をマップ上に表示させるアプリを作りました。
ごくごく簡単なものになりますのでササッと。

# アプリケーションの動き
1. ユーザーがフォームから住所を投稿
2. 住所を緯度経度に変換
3. 変換した移動軽度から、画面上のマップにマーカーを反映させる。

な感じです。

# 準備
駆け足で書いていくため、最初の手順は省きます。
取り敢えず、
``` rails new ``` がされている状態から始めます。

# Gemfileに追記
Gemfileに以下を加え、bundle installを実行します。

```ruby
# map表示を簡易化する
gem 'leaflet-rails'
# map上のマーカー周りをゴニョゴニョする
gem 'leaflet-markercluster-rails'
# 住所を緯度経度に変換する
gem 'geocoder'
```

# 設定ファイルを追加
config/initializersに以下のファイルを追加

```ruby
Leaflet.tile_layer = "http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
Leaflet.attribution = 'Map data &copy; <a href="http://openstreetmap.org">OpenStreetMap</a>'
Leaflet.max_zoom = 18
```

特に難しい設定ではなくて、見てのとおりですね
tile_layerを書き換えれば、OpenStreetMapだけでなくgoogle mapやらも使うことが出来ます。


# scaffoldでササッと投稿アプリを制作
Railsの魔法ことScaffoldで、簡単にユーザー投稿アプリを作ります。

```shell
rails g scaffold maps name address comment:text lonlat
```

それぞれ

- name:住所を投稿したユーザの名前(なくていい)
- address:投稿された住所
- comment:なにかしらのコメント
- lonlat:投稿された住所を(内部的に)緯度経度変換し保存する

です。

緯度経度(lonlat)はユーザーに入力させたくないので、_form.html.erbから該当箇所を削除しておきます。

最後に```rails db:migrate```も実行。

# leafletでマップを表示する
今回は『Open Street Map』を使用します。

## leafletを使うための準備
まずleafletを使用するため、application.jsとapplication.cssに以下を追加します。

application.js

```javascript
//= require leaflet
//= require leaflet.markercluster
```

application.css

```css
 *= require leaflet
 *= require leaflet.markercluster
 *= require leaflet.markercluster.default
 */
```

## 適当なマーカー用画像を用意
今回は、取り敢えず"marker.png"という画像を/Publicに追加したということで進めます。

## leafletを使ってマップを表示
maps/indexに以下のコードを追記します。

```erb

（省略）
<div id="map" style="height: 500px; width: 500px;"></div>
<%=
  map(:center => {
      :latlng => [36, 140],
      :zoom => 4,
  })
%>
<script>
  // rubyから渡された住所配列をjsの変数に格納
  var maps = <%= @maps.to_json.html_safe %>;

  for(var hash_count = 0; hash_count < maps.length; hash_count++){
    // 緯度経度とコメントを取り出しマーカー化
    L.marker(maps[hash_count].lonlat.split(','), {icon: L.icon({iconUrl: "/marker.png"})},)
      .bindPopup(maps[hash_count].comment)
      .addTo(map);
  }
</script>
```

scriptタグの中はこちらの書き方の方がスマートでいいですね

```erb

  <% @maps.each do |map| %>
    L.marker("<%= map.lonlat %>".split(','), {icon: L.icon({iconUrl: "/cycle24.png"})},)
    .bindPopup("<%= map.comment %>")
    .addTo(map);
  <% end %>

```

# 投稿された住所を緯度経度に変換する
ユーザーが住所を入力し保存(あるいは更新)する際に、住所を緯度経度に変換しlonlatカラムに保存するための仕組みを作ります。

```ruby
class Map < ApplicationRecord
    before_save :update_lonlat

    def update_lonlat
        lonlat = address_to_lonlat(read_attribute(:address))
        write_attribute(:lonlat, lonlat)
    end

    # 住所を保存用経緯度に変換
    def address_to_lonlat(address)
      result = Geocoder.search(address)
      lonlat = result.first.coordinates
      return lonlat.join(',')
    end
end
```

これだけで、住所(address)カラムを保存、更新した際に緯度経度(lonlat)カラムも更新してくれます。

# 完成
上記の手順でおそらく完成するはずです。
![FireShot Capture 023 - MapTest - mrbicycle-map-test.herokuapp.com.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/165044/c68f2e75-a2ce-dad8-4210-26b0adbdcf02.png)

寝る前にササッと書いているのでかなり駆け足でしたが、お読み頂きありがとうございました。
【Python】Gmail送信機能

<h6>通知機能が欲しくて、gmailを飛ばす機能を作ったので記載します。
言語はpythonになります。


---

<h3>前提
<h6>gmailの初期設定では、pythonによるログインをセキュリティでブロックしています。
解除方法は、Gmailアカウントにある「安全性の低いアプリのアクセス」の設定を許可にすればOKです。
https://myaccount.google.com/security

---
送信メールの設定を行うクラスになります。
送信元、送信先、gmailのアカウントパスワードを初期化で設定し、
sendメソッドの引数の内容を設定します。


```python:send_message.py
Learn more or give us feedback
from email.mime.text import MIMEText
from email.utils import formatdate
import smtplib

class Send_Message:
    fromaddress = 'sample@gmail.com'
    toaddress = 'sample@hotmail.co.jp'
    password = 'password'

    def __init__(self, fromaddress, toaddress, password):
        self.fromaddress = fromaddress
        self.toaddress = toaddress
        self.password = password


    def send(self, content):
        smtpobj = smtplib.SMTP('smtp.gmail.com', 587)
        smtpobj.ehlo()
        smtpobj.starttls()
        smtpobj.ehlo()
        smtpobj.login(self.fromaddress, self.password)

        msg = MIMEText(content)
        msg['Subject'] = 'subject'
        msg['From'] = self.fromaddress
        msg['To'] = self.toaddress
        msg['Date'] = formatdate()

        smtpobj.sendmail(self.fromaddress, self.toaddress, msg.as_string())
        smtpobj.close()
```

メインの処理になります。
ここで、送信元、送信先、パスワード、内容を設定し、
実行すればgmailにログインし、メールを送信します。

```python:mail.py
from  send_message import Send_Message
import sys

def main():
    fromaddress = '@gmail.com'
    toaddress = '@gmail.com'
    password = ''
    content =""

    try:
        mail = Send_Message(fromaddress, toaddress, password)
        mail.send(content)
        print("success")
    except:
        print("error")

if __name__ == "__main__":
    main()
```


githubにソースをあげています。
https://github.com/kurihiro0119/gmail_send_API
Xorshiftを移植してみた

JavaScript で実装した XorShift を Haskell に移植しました。[既存の実装](https://hackage.haskell.org/package/xorshift)は知っていますが、ライブラリが追加できない環境で手軽に使いたかったので移植しました。

オンラインで実行 ([Repl.it](https://repl.it/))

* https://repl.it/@7shi/Xorshift32

移植元

* [Xorshiftなどの擬似乱数をプロットして比較してみた](https://qiita.com/7shi/items/8219dcc22950253b26fb)

# Xorshift

Xorshift は実装が簡単な割に良好な擬似乱数を生成します。

* [Xorshift - Wikipedia](https://ja.wikipedia.org/wiki/Xorshift)
* [Google Chromeが採用した、擬似乱数生成アルゴリズム「xorshift」の数理 – びりあるの研究ノート](https://blog.visvirial.com/articles/575)

シード値を渡すと擬似乱数を返します。これは次のシード値として使います。

```haskell
import Data.Bits (xor, shiftL, shiftR)
import Data.Word (Word32)

getNext :: Word32 -> Word32
getNext seed = s3 where
  s1 = seed `xor` (shiftL seed 13)
  s2 = s1   `xor` (shiftR s1   17)
  s3 = s2   `xor` (shiftL s2    5)
```

シード値から一意に決まるため参照透過です。

# シード値

ナノ秒単位で現在時刻を取り出してシード値を作ります。シード値 0 からは 0 しか得られないため、32bit 化して 0 になった場合はやり直します。

```haskell
import Data.Time.Clock.POSIX (getPOSIXTime)

getSeed :: IO Word32
getSeed = do
  t <- getPOSIXTime
  let ret = floor $ t * 1e9 :: Word32
  if ret == 0 then getSeed else return ret
```

現在時刻は毎回異なり参照透過ではないため IO モナドです。

# 浮動小数点数化

得られた擬似乱数を 0 以上 1 未満の浮動小数点数に加工します。

```haskell
word32MaxNext :: Num a => a
word32MaxNext = 2 ^ 32

getFloat :: Fractional a => Word32 -> a
getFloat w32 = (fromIntegral w32) / word32MaxNext
```

※ `fromIntegral` で型変換してから割り算します。

# ラップ

IO モナドの中で簡単に使えるように、シード値の初期化から一連の流れをラップします。

```haskell
import Data.IORef (newIORef, readIORef, writeIORef)

rand :: Fractional a => Word32 -> IO (IO a)
rand seed = do
  s <- newIORef seed
  return $ do
    oldSeed <- readIORef s
    let newSeed = getNext oldSeed
    writeIORef s newSeed
    return $ getFloat newSeed
```
```text:実行例
> rnd <- rand =<< getSeed
> rnd
=> 0.15449975966475904
> rnd
=> 0.31265981029719114
> rnd
=> 0.979753604857251   
```

[オンライン実行環境](https://repl.it/@7shi/Xorshift32)では [run ▶] で実行した後に、REPL で上記の実行例が試せます。

# テスト

10 回のループで値を確認します。

```haskell
import Control.Monad (sequence_)

main :: IO ()
main = do
  rnd <- rand =<< getSeed
  sequence_ $ replicate 10 $ print =<< rnd
```
```text:実行例
0.7494283774867654
0.19796228897757828
0.4463836853392422
0.19902197853662074
0.39511674898676574
0.46158441342413425
0.4156568821053952
0.8667732949834317
0.5666300777811557
0.7868200021330267
```

※ シード値は現在時刻に依存するため、実行結果は毎回異なります。

# 経緯

Repl.it はオンライン開発環境としては割と使い勝手が良さそうでしたが、Haskell ではライブラリの追加がサポートされていないようです。

* [Repl.it - How to import library files?](https://repl.it/talk/ask/How-to-import-library-files/15088)

※ Python のサポートは手厚く `import` するだけで自動的に追加されます。

乱数が必要な用途で使おうとして困りました。仮に JavaScript で実装を始めましたが、標準の乱数ではシード値を設定することができなかったため、自前で Xorshift を用意する羽目になりました。自前で用意するなら Haskell だって一緒だと思い、移植しました。

# 参考

IO モナドの基本的な使い方は以下を参照してください。

* [Haskell アクション 超入門](https://qiita.com/7shi/items/85afd7bbd5d6c4115ad6)
jQuery 楽天APIを必要最低限で動かす

# 注意
この記事は、2年ほど前にQiitaに投稿した記事の再投稿になります。
若干内容が古くなっている可能性があります。

<p>
楽天APIを使用して、inputに打ち込んだ単語に関連する商品をドバっと垂れ流す仕組みを作ります。
</p>

<h2>1. 楽天API アプリの新規作成</h2>

<p>
https://webservice.rakuten.co.jp/document/<br>
このページの右上、「アプリID発行」からなんやかんやで発行。<br>
（この辺りは他の方の記事を参照のこと）<br>
ちなみに「アプリURL」ですが、あくまで勉強としてローカル環境でのみ動かしたい場合は、適当に自分のGitHubページのURLなどを使用します。（人のページは勝手に使わないこと！）
</p>

<h2>2. HTML</h2>

```html
<input type="text" id="search_area">
<button type="button" id="search_button">検索&lt;/button>
<ul></ul>
```

<h2>3. JavaScript</h2>

```JavaScript
$(function(){
  $('#search_button').on('click', function(){
    var keyword = $('#search_area').val();
    $.get('https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?', {
      applicationId: "1046798079875156979",
      keyword: keyword
    }, function(data){
      if (data.count > 0){
        $.each(data.Items, function(i, item){
          var temp = $(`&lt;li>&lt;a href="${item.Item.itemUrl}">&lt;img src="${item.Item.mediumImageUrls[0].imageUrl}">&lt;/a>&lt;/li>`);
          $('ul').append(temp);
        })
      }
    });
  });
});
```

<h2>出力結果</h2>

<img src="https://qiita-image-store.s3.amazonaws.com/0/165044/31001704-a4de-288c-69c5-ec99d041b869.png" alt="rakuten">

<h2>補足</h2>

<p>
$.get('https://~~~~ の部分<br>
ここは、色々書き方があって、
</p>

<pre class="code">
$.ajax({
  type: 'get',
  url: 'https://app.rakuten.co.jp/services/api/IchibaItem/Search/20170706?',
  data: {
    applicationId: "1920314253647586970", // 自身のapplicationIdを入力してください。この数字は適当です。
    keyword: keyword,
    hits: 20
  }
</pre>

<p>
と書いても一緒です
</p>

<p>
返ってきたデータは、上記のコードだと <span class="code">item.Item.itemUrl</span> や <span class="code">item.Item.mediumImageUrls[0].imageUrl</span> として抜き出しています。
この辺りは各APIにより微妙に違ってくるので、dataをコンソールでよく確認しながら目当てのデータを抜き出してください。
</p>
Github pages + Jekyllでブログ作成(will-jekyll-template)

<p>
たまたま知り合いが Github Pages でブログを公開していたので、私もさくっと作成してしまおうかと思います。<br>
使用するのは、Jekyllという静的サイトジェネレータ(SSG)に決定。<br>
SSGを色々と調べてみると、Goで書かれている <a href="https://gohugo.io/">HUGO</a> が今は熱いようですが、Github Pages が公式にJekyll を推奨しているので、今回はJekyllを使用しました。
</p>

<p>
テーマは、<a href="https://github.com/willianjusten/will-jekyll-template">will-jekyll-template</a> を使用しました。おしゃれでシンプル。
</p>

<p>
手順を簡単にメモしておきます。
なお、Rubyの導入は飛ばしています。
</p>

<h2>プロジェクトの準備</h2>

<p>
まずは、<a href="https://github.com/willianjusten/will-jekyll-template">will-jekyll-template</a> をクローンします。<br>
クローンしたリポジトリは好きな名前に変更してしまっても大丈夫です。
</p>

<p>
そのあと、cdコマンドで該当のフォルダに移動し、<span class="code">init</span> を実行。<br>
bundleはそのままだとなんのgemも入っていないので、下記のように変更しました。
</p>

```ruby:Gemfile
gem "minima", "~> 2.5"
gem "github-pages", group: :jekyll_plugins
```

<p>
設定したら、`bundle install --path vendor/bundle --jobs=4` を実行。<br>
結構たくさんのGemが入るので、そこそこ時間がかかります。
このままだと、ビルドしたときに *vendor/* 以下のファイルまでビルドされてしまいエラーが出るので、*_config.yml* の `exclude:` を下記に変更。<br>
</p>

```yaml:_config.yml
exclude: ['package.json', 'src', 'node_modules', 'vendor']
```

これでブログの作成は完了。
`npm install` と `bundle exec gulp` を実行したらローカルで動かせます。

<h2>感想</h2>

<p>
作り始める前は簡単に出来るだろうと思っていましたが、思った以上に手こずりました...<br>
正直始める前はこういったブログの作り方があるのも知りませんでしたが、やってみると結構いい感じ。<br>
テーマの数も多いし、自分でデザインを微調整することも出来る。
</p>
<p>
それにしてもGithub Pagesは凄い。<br>
静的サイトジェネレータを使えばセキュリティ面も安心ですし、無料でSSL化もできちゃう。
いいですなぁ。
</p>
【MacOS】やろうよLaravel環境設定


#目的
LaravelをMacにインストールしたので、備忘録です。
完全初心者向けに書いているので、初めての方も是非参考にしてみてください。

#この記事で出来ること
- Laravel、Composer、PHPをインストールすることが出来ます。
- Laravelを使ってプロジェクトを作成出来ます。
- Laravelで作ったプロジェクトをWEBブラウザで表示出来ます。

#使用する環境
MacOS 10.15.2
Laravel 6.15.1
PHP 7.3.14

#環境構築編
##Homebrewをインストールしよう

https://brew.sh/index_ja

ターミナルに指定のコマンドを流し、（念のため）下記のコマンドを流してください。

```
brew update
```

##PHPを入れてみよう

```
brew install php@7.3
```

###ポイント
・phpはusr/local/etc/php/7.3/以下に設定ファイル入る
・念のためバージョン確認してみましょう。

```
php -v
```

##Composerを入れてみよう

https://getcomposer.org/

`Get Started` => `Downloading the Composer Executable` => `Globally` => `the Download page instructions`
下記URLに記載されているコマンドを順に実行します。（一個ずつ！）

https://getcomposer.org/download/

usr/local以下に配置してあげましょう。（コマンドラインから使えるようにします。）

```
mv composer.phar /usr/local/bin/composer
```

##Laravelを入れてみよう

Laravelをインストール。
https://readouble.com/laravel/4.2/ja/quick.html

※ここらへんで詰まることあるので、参考記事
https://qiita.com/Shogo1992/items/6b6609087f97bff717c7

```
composer global require laravel/installer
```

環境変数に追加
ホームディレクトリに移動してください。

```
cd ~
```
環境変数を設定するファイル（.bash_profile）があるか確認し、変数追加してください。

```
vi .bash_profile
```
（`e`を入力するとEdit出来ます。終わったらesc押して`:q`で離脱）
これを追加

```
export PATH="$HOME/.composer/vendor/bin:$PATH"
```

変数を有効化しましょう。

```
source .bash_profile
```

#プロジェクト作成編

##プロジェクトを作成してみよう

プロジェクト名を決めてプロジェクトを作成しよう。
※プロジェクトとは
Laravelの標準セットが備わった一つのフォルダを作成することです。
ここにLaravelで必要なソースコードがインストールされています。

```
composer create-project laravel/laravel 【プロジェクト名】
```
###作成されるフォルダ説明
- app（処理を記述）
- config（各種設定ファイル）
- database（データベース設定）
- public（ファビコンなど）
- resources（view）
- storage（データを保存）
- tests（ユニットテスト）
- vendor（外部のライブラリを格納）


##サーバーを起動してみよう

```
php artisan serve
```

localhost:8000にブラウザからアクセスしてみよう。

無事Laravelのロゴ画面が表示されたら完了です。お疲れ様でした。
coc-metalsのNo Build Targetエラーを解決(vim-cocのプロジェクトルート認識の修正)

# 解決方法

早速ですが、解決方法を記載していきます。
このエラーはbuild.sbtなどをvim側がうまく発見できずに発生しているエラーのため「build.sbtがあるのに何故？」というときに参考になるかもしれません。

## 前提

以下のような状態で発生する、該当エラーについては解決が可能です

- gitリポジトリのルートディレクトリ以外にbuild.sbtが配置されている

## 対応

cocのvim設定に以下を追加してください。

```vimscript
autocmd FileType scala let b:coc_root_patterns = ['build.sbt']
```
これで正常に動作するようになります。

# 詳細

今回私は以下のようなプロジェクト構成でこのエラーにハマりました。

```sh
repository
├── .git
├── documents
└── project_root
    └── build.sbt
```

この構成でproject_root以下でvimからscalaファイルを起動しても、何故かrepository直下に.metalsファイルが作成されてしまいNo Build Targetエラーになってしまいました。

いろいろ調べた結果以下のリンクに記載されているものを設定すれば正しくプロジェクトルートを読み込ませてあげることができそうだということがわかりました。

[cocのワークスペース設定についてのドキュメント](https://github.com/neoclide/coc.nvim/wiki/Using-workspaceFolders)

`"coc.preferences.rootPatterns"`のデフォルト設定に`.git`がありますね。怪しいです。
通常cocは.gitファイルがある場所をrootとして認識しながら起動するようになっているということみたいです。

修正方法としては少なくとも以下の2通りがありそうです
1. cocの設定ファイルでcoc.preferences.rootPatternsを修正する
2. ファイルパターンにより変数を上書きして修正する

私は今回は2のパターンを採用して修正しました。
それが対応ブロックに記載されている修正内容です。

配列の先頭にあるものから順にマッチしていくのかな？と思うので2つ目以降の要素はデフォルト設定を残しても良いのかもしれませんが、面倒なので検証していません。

# まとめ

あんまりvim-metalsで開発している人はいないような気がしますが、cocのルートディレクトリ指定のせいでハマって悩んでる人は稀によくいるかもしれないので、少しでも参考になれば幸いです。

# 追記: 2020-02-18

公式のWikiによくある問題として本記事の内容が記載されていました。  
ちゃんと確認できていなかったですね...

https://github.com/scalameta/coc-metals/wiki/Common-Problems

プラスアルファで有用な情報も記載されているので、こちらも必見です
Google Apps Scriptってなんだっけ？

お仕事で[G suite](https://gsuite.google.co.jp/intl/ja/features/)にふれる機会が増えたため、業務効率アップのため[Google Apps Script](https://developers.google.com/apps-script)を書けるようになりたいので、まずは収集した情報をまとめようと思います。

#はじめに
Google Apps Script（略称：GAS（ガス））は、Googleが提供しているプログラミング環境です。
ExcelのVBAと似た感じで、スプレッドシートでGASを使っている事例が多く公開されていますが、それ以外にもGmail、、Googleカレンダー、ドキュメント、フォーム、翻訳、Google MapなどのGoogleが提供しているサービスについても同様に、GASから操作できます。

時間などでトリガーが設定できるので、例えば毎朝8:00にGASのプログラムを自動で起動してスプレッドシートのデータを最新化してPDF化し、Gmailに添付して関係者に送付する、といったルーチン業務の自動化もできます。

#開発環境
Google Apps Scriptでプログラムを作成するには、
1. インターネットにつながるPCを準備し、
2. ブラウザ（Chrome推奨です）をインストールして、
3. Googleアカウントを作成する
で準備完了！

めっちゃ簡単:clap::clap::clap::clap:

chromeに拡張機能としてGASを追加したり、GASの拡張機能もあるみたいです。


次からは、実際にプログラム書いていきたいと思います。

###参考
[Google Apps Script 入門](https://qiita.com/t_imagawa/items/47fc130a419b9be0b447)
[【保存版】初心者向け実務で使えるGoogle Apps Script完全マニュアル](https://tonari-it.com/google-apps-script-manual/)
[業務効率が上がる!Google Apps Scriptとは【初心者向け】](https://techacademy.jp/magazine/19766)
[3分で始めるGAS(Google Apps Script)｜開発環境の起動からコード実行まで](https://tanuhack.com/begin-gas/)
[GASの開発が捗るGoogle Chromeの拡張機能３選](https://tanuhack.com/gas-chrome-extensions/)
Tech系Youtubeチャンネル（カンファレンス系）

Youtubeのカンファレンス動画や公式チャンネル動画をダウンロードして、外出時にバックグラウンド再生して歩きながら聴くのが好きです。
カンファレンス動画を紹介します。

[公式チャンネルはこちら](https://qiita.com/tetsuyaohira/items/cb55bfb2a7f22509d4a0)
[個人チャンネルはこちら](https://qiita.com/tetsuyaohira/items/249c5c4392cd238134fc)

# 国内
## PHPer Kaigi
https://www.youtube.com/channel/UCjRTsAj3qtcvnTj6IriRwgg
## PHP Conference Japan
https://www.youtube.com/channel/UCidF7e14IfNE6wCJ9sfJQ6w
## PHPカンファレンス福岡 phpconfuk
https://www.youtube.com/channel/UCoDkBdCiMDLZebhXsBJlXUA
## builderscon
https://www.youtube.com/channel/UCg2yManNPkrPTB1ffhHJu5g
## nextwebconf
https://www.youtube.com/channel/UCFq8UHBXg8YNHCeaGmtSFEw
## Frontend Conference Fukuoka 2019
https://www.youtube.com/channel/UCCIX9oXb-_n_6S7ap65WMEg/featured
## html5j
https://www.youtube.com/channel/UCGiSzzfTs7s3dHy3xWkSQ0g
## Inside Frontend
https://www.youtube.com/channel/UCIXvE12FNUi9sPkoUWqIXtQ/videos
## PWA Night
https://www.youtube.com/channel/UCScKlu7f-HZ5To_uBsT6zOw
## jsconfjp
https://www.youtube.com/channel/UC8cSEtE64EryVpQDVqHM_Gg
## Vue.js日本ユーザーグループ
https://www.youtube.com/channel/UC6KPwA1kZJtQYdlh8_2hxCA
## iOSDC Japan
https://www.youtube.com/channel/UCF-W8FRL7d_9konHA9eNObA
## DroidKaigi
https://www.youtube.com/channel/UCgK6L-PKx2OZBuhrQ6mmQZw
## JapanAndroidGroup Live Channel(日本Androidの会ライブチャンネル)
https://www.youtube.com/channel/UCEgcvRMuUx49r96YRSrab0Q
## Matsue.rb
https://www.youtube.com/channel/UCW1yvUzdRW2GVQIYP7h314A
## PyConJP
https://www.youtube.com/channel/UCxNoKygeZIE1AwZ_NdUCkhQ
## yapcasia
https://www.youtube.com/channel/UCTqv2OjSox70MM7iYftlsIw
## RubyWorld Conference
https://www.youtube.com/channel/UC2PkIxfxN1tX91uVsbX3I6Q
## しまねOSS協議会
https://www.youtube.com/channel/UCV5zrptA8_cSIJCkx22M4MA
## Scala Matsuri
https://www.youtube.com/channel/UC6DFHglgVXQUVDbUmQHtxDQ
# 海外
## JSConf
https://www.youtube.com/channel/UCzoVCacndDCfGDf41P-z0iA
## React Conf
https://www.youtube.com/channel/UCz5vTaEhvh7dOHEyd1efcaQ
## RubyKaigi
https://www.youtube.com/channel/UCBSg5zH-VFJ42BGQFk4VH2A
## GOTO Conferences
https://www.youtube.com/user/GotoConferences
## Spring I/O
https://www.youtube.com/channel/UCLMPXsvSrhNPN3i9h-u8PYg
## PyCon 2019
https://www.youtube.com/channel/UCxs2IIVXaEHHA4BtTiWZ2mQ/videos
## VMworld
https://www.youtube.com/channel/UCaC9l9CYIEazFB5-pWfCNKw
## Red Hat Summit
https://www.youtube.com/user/redhatsummit
## Salesforce Events & Dreamforce
https://www.youtube.com/user/dreamforce
## SAPPHIRE NOW
https://www.youtube.com/user/sapphirenow
## RSA Conference
https://www.youtube.com/channel/UCYzwGkfOqrevO-4TuTjPLwQ
## Plone
https://www.youtube.com/channel/UCbyShiqfZ7Xg_n3R1gynpxw/videos
## try! Swift Conference
https://www.youtube.com/channel/UCuPue-GLK4nVX8klxQITIOw
## Rust Belt Rust Conference
https://www.youtube.com/channel/UCptxtVyJkQAJZcFwBbIDZcg/featured
## Code Sync
https://www.youtube.com/channel/UC47eUBNO8KBH_V8AfowOWOw/featured
## InfoQ
https://www.youtube.com/nctv/featured
Codeforces Round #620 C. Air Conditioner 範囲の管理でYES/NO

# 概要
以下が実現可能かをYES/NOで述べよ
- `n`人のお客さんがくる。今の部屋の温度は`m`。今の時間は`0`
- 時間`1`ごとに部屋の温度は`+-1`か変えないことができる。(つまり、５秒あれば$+1度 \rightarrow -1度  \rightarrow -1度  \rightarrow 変えない \rightarrow 変えない$などができる)
- n人目のお客さんは`t`の時間に来るが、部屋が`l`以上, `h`以下でなければならない

# アプローチ

- 部屋の気温は今と次のお客さんの到着時間の差`dt`分だけ操作できます。今の室温をmとするならm-dtからm+dtに変化させることが可能です。これをそれぞれ、`cl`, `ch`(can lowとcan high)とします。お客さんの許容範囲[l, h]がこれと重ならなければNGです。(この判定は、許容下限がCHより大きいか、許容上限がCLよりも低いとNGになります)
- もし、許容できる場合、部屋の温度は[max(cl, l), min(ch, h)]の区間に調整されます。気温をいくら低くできたとしても(cl), お客さんの許容限度(l)以下に下げてはいけません。いくら熱くできたとしても(ch),お客さんの許容限度(h)以上に上げてはいけません。これを新しい$[cl, ch]$とします。
- 次のお客さんに備えて調整可能な範囲は次のお客さんが来るまでの時間を再度`dt`としたとき、$[cl - dt, cl + dt]$の間で調整できます
以上を繰り返せばOKです。(尚、実装上は最初のmを$cl=ch=m$としておきます)

# コード
```Python
q = int(input())
    for _ in range(q):
        n, m = map(int, input().split())
        f = True
        curTime = 0
        canLow = canHigh = m
        dat = []
        for _ in range(n):
            visitTime, needLow, needHigh = map(int, input().split())
            dat.append((visitTime, needLow, needHigh))
        for visitTime, needLow, needHigh in dat:
            deltaTime = visitTime - curTime
            canLow -= deltaTime
            canHigh += deltaTime
            if needHigh < canLow or canHigh < needLow:
                f = False
            curTime = visitTime
            canLow = max(needLow, canLow)
            canHigh = min(needHigh, canHigh)
        print("YES" if f else "NO")
```
https://codeforces.com/contest/1304/submission/71150285
Codeforces Round #620 B. Longest Palindrome

# 概要
- m文字の文字列がn個与えられる
- これらを使って(つなぎ合わせて)回文が作れるか調べろ。作れる場合、その例を１つあげよ)
- 制約: $1<=n<=100$, $1 <= m <= 50$

# アプローチ
この問題はすべての文字がm文字であり、nが小さいため、ブルートフォースで解決できます。
まず、回文の文字列を以下のように考えます。
$回文文字列 = sleft + scenter + sright$

- left/rightについて
自分と逆になる文字列がいればそれを左右に結合します。
ここで例えば、$bat$と$tab$を見つけた場合、それぞれ、$sleft += "bat"$, $sright = "tab" + sright$してやると、回文が保たれます。一度使った文字列はもう使ってはいけません。(実装上はリストから文字列を削除しています。高々n=100以下なのでdelしています)

次に、$scenter$になりうる文字列があるかを判別します。これは単体の文字列で回文かを試せばよいです。これも、一度判定したらもう使ってはいけません。

```Python
n, m = map(int, input().split())
s1 = s2 = sc = ""
dat = []
for _ in range(n):
    dat.append(input())

while 0 < len(dat):
    s = dat[0]
    del dat[0]
    if sc == "": # 単独で回文かを判定
        if s == "".join(reversed(s)):
            sc = s
            continue
    # 残りに自分の反転文字列があればそれを採用
    for j in range(0, len(dat)):
        ss = "".join(reversed(dat[j]))
        if s == ss:
            s1 = s1 + s
            s2 = dat[j] + s2
            del dat[j] # 使った文字列は削除
            break # 1つ見つかればその先は探さない

res = s1 + sc + s2
print(len(res))
print(res)
```
https://codeforces.com/contest/1304/submission/71135752
Codeforces Round #620 A. Two Rabbits


AtCoder ABC B問題レベル。

# 概要
- 2匹のウサギがx1, x2の座標にいる
- それぞれa,bの速度で互いに走るとき、同じ位置に達することがあるか？

#　アプローチ
距離$x2-x1$ を 毎ターン $c = (a + b)$ずつ動くので、割り切れるかを判定すればよい。


本番ではなぜか、商がintかを判定してしまいましたが、$dis $ c == 0$かを判定すればよいです。

```Python
    q = int(input())
    for _ in range(q):
        x, y, a, b = map(int, input().split())
        dis = y - x
        c = a+b
        res = dis / c
        if res.is_integer():
            print(int(res))
        else:
            print(-1)
```
https://codeforces.com/contest/1304/submission/71126096
Codeforces Round #559 A. A pile of stones

# 題意
- あなたは最初`x`個の石を持っていた
- `+` (石を場からとる)か `-` (石を場に置く)をした
- この間`-`にて手元から石がなくなることはなかった
- 最後に手元にある石の最小数を述べよ

# アプローチ
最初に0個石を持っていたとして、足りなくなる最小の石の数を求めます。この分の石を最初持っておけばよいです。
この数の石を初期値にした上で、再度シミュレーションすればよいです。
※あるいは上記で求めた最後の値にこの足りなくなる数を足しても良いです。(コードはこちらのアプローチ)

```Python
n = int(input())
s = input()
mi = 0
c = 0
for i in range(n):
    if s[i] == "+":
        c += 1
    else:
        c -= 1
        mi = min(mi, c)
c -= mi
print(c)
```
https://codeforces.com/contest/1159/submission/71169628
sfdx force:source:deployの出力JSONで成否を判定して終了コードをちゃんと設定する


# ネットワークエラーが出てもexit statusが0...?

Travis(Ubuntu 16.04.6 LTS)で`sfdx force:source:deploy`コマンドを使ってSandboxでテストを実行しているのですが、更新かけたばかりのSandboxだったからか`getaddrinfo ENOTFOUND`が出て失敗していました。
（ホスト名だけ変えてあります）

```
$ sfdx force:source:deploy -u sandbox -m ApexClass,ApexTrigger --testlevel RunLocalTests --checkonly --verbose --json -w 9
Unhandled rejection Error: getaddrinfo ENOTFOUND hogehoge-sandbox.cs114.my.salesforce.com hogehoge-sandbox.cs114.my.salesforce.com:443
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
The command "sfdx force:source:deploy -u sandbox -m ApexClass,ApexTrigger --testlevel RunLocalTests --checkonly --verbose --json -w 9" exited with 0.
```

が、なぜか**`exited with 0`を返してくるのでCI的には成功してしまうという...**


# 結果のJSONでちゃんと判定する

`--json`を指定していると、結果をJSONで標準出力に返してくれるので、それでちゃんと判定してみます。

## `jq --exit-status` で結果のJSON内容で終了コードを変える

デプロイコマンドの後に `jq --exit-status .result.success` でパイプして`jq`コマンドで`{"result":{...(略)..., "success":false}}`が返ってきたときに失敗させます。

エラー出力に非JSONのエラーメッセージだけ出た場合は`jq`がパースに失敗して非0な終了コードにさせるために`2>&1`します。


```
sfdx (略) 2>&1 | jq --exit-status .result.success
```

参考: http://hoppie.hatenablog.com/entry/2016/07/29/142935


## 失敗した時は結果のJSONをログとして出力したい

パイプで`jq`コマンドに流してしまうと失敗したときもJSONが見れなくなってしまうので`tee`を使って一時的にファイルにもJSONを吐き出しておいて、失敗の場合だけ`cat`で表示させます。

```
SUCCESS=$(sfdx (略) 2>&1 | tee result.json | jq --exit-status .result.success)
if [ "$SUCCESS" != "true" ]; then cat result.json; fi
```

## 最終的な`.travis.yml`の抜粋

```
  - SUCCESS=$(sfdx force:source:deploy -u sandbox -m ApexClass,ApexTrigger --testlevel RunLocalTests --checkonly --verbose --json -w 9 2&>1 | tee result.json | jq --exit-status .result.success)
  - if [ "$SUCCESS" != "true" ]; then cat result.json; fi
```
【Gradle】ビルド時にktlint（に限らずタスク類）を走らせる【Kotlin】

# やること
`Kotlin`のプロジェクトで、`compileKotlin`時に`ktlint`を走らせます。
また、環境変数によって実行結果を分けます。

`build.gradle`は`Kotlin-DSL`で書きます。

## 準備: ktlintの導入
以下のように行いました。

```kotlin:build.gradle.kts
plugins {

    /* 略 */

    id("org.jlleitschuh.gradle.ktlint") version "9.2.1"
}
```

# やりかた
以下のように、`compileKotlin`タスクに`dependsOn`で`ktlint`の実行を指定してやればできます。
サンプルではビルド前にフォーマッティングまでやっています。

```kotlin:build.gradle.kts
tasks.compileKotlin {
    dependsOn("ktlintFormat")
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
```

## 応用
環境変数を使って「ローカルでは自動修復してエラー無しで続行、CI環境ではエラー」というように動作を分けることもやってみました。

```kotlin:build.gradle.kts
tasks.compileKotlin {
    val lintOption: String = if (System.getenv("IS_CI")?.toBoolean() == true) {
        "ktlintCheck" // CI環境ならチェック（失敗すると落ちる）
    } else {
        "ktlintFormat" // CI環境じゃなければfix（自動修正を走らせる）
    }

    dependsOn(lintOption)
    kotlinOptions {
        jvmTarget = "1.8"
    }
}
```

# 参考にさせて頂いた記事
- [ktlint\-gradleの導入と使用について \- Qiita](https://qiita.com/hiko1129/items/5ec06281e8464117c087)
初心者がPythonとOpenCVを触ってみた①～環境構築編～

皆さん、こんにちは！！
初投稿です。
なのでお見苦しい文章になったり間違った理解の仕方などが多いとは思いますがご容赦ください。
さて、ここからが本題となるのですが私ははっきり言って初心者です。
なので今回は少しPythonとOpenCVについて触ってみようと思って書いております。
初めに今回使用している環境などを示します。
#使用環境
PCスペック
CPU  :intel core i5 4300U
Mem:8GB
OS:windows10 pro 64Bit

使用ソフト
Anaconda3
spyder(pythone3.7)

#セットアップ

まずは環境がなかったので環境構築から始めます。
今回は前述の通りソフトはanaconda3を利用します。またIDEはspyderを使います。
また、使用するPythonのバージョンは3.7です。
まずはソフトの入手から。
各々利用しているWebブラウザの検索バーに"anaconda"と入力しおそらくトップに出てくるものもしくは
https://www.anaconda.com/
にアクセスしanacondaをインストールしてください。


ダウンロードが終了したらソフトを起動してみましょう。
![スクリーンショット (4).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373257/3708287e-8915-a731-6839-a15a5922da5d.png)

起動したらおそらくこのような画面になるはずです。
この中から今回はSpyderというIDEを使用します。
Spyderの下がinstallというボタンの場合はinstallしてください。
もしlaunchになった場合はそこのボタンを押してIDEを起動することができます。

ここまででソフトのインストールは終了です。
また、この中でVScodeというソフトは何かと便利なエディタなのでインストールしておくことをお勧めします。

##OpenCV環境整備
ここからはOpenCVを使用するための環境構築を行います。
まずはWindowsキーを押下し、検索欄にAnaconda Promptをと入力し起動します。

![スクリーンショット (6)_LI.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/373257/1d50cc40-78f7-7e3f-5d58-9ce2c02c0bed.jpeg)

するとこのようなウィンドウが開くと思います。


```
conda create -n py37 python=3.7 anaconda
```


このコマンドをanaconda pprompt上で入力し、Python3.7の仮想環境を作成しておきます。
仮想環境をこのように構築することによりPython2.7用など複数の環境を作成するときに便利になります。

```
pip install opencv-python

pip install opencv-contrib-python
```
上記のコマンドを入力することで必要なライブラリなどを落とします。

入力後エラーなどが発生しなければ今回環境構築などは無事終了です。
お疲れさまでした。
最後に初心者のつたない文章でしたがここまで読んでいただきありがとうございました。
次回記事を書くのは少し時間が空くとは思いますが、実際にプログラムを軽く行い動作できるか、利用ができるか確認していきます。
ありがとうございました、また次回の記事でお会いしましょう。
バイバイ！

*/2020/12/06 リンクがおかしくなっていたため修正/*
「javadoc エラー - input length = 1を読み込めません」の解決法

eclipseからjavadocを出力しようとしたとき、「javadoc エラー - input length = 1を読み込めません」のエラーが発生する場合があるが、検索しても解決方法が出てこなかったため、私が解決した方法をここに記載しておく。

# 解決方法
## Javaのバージョン違い
私の場合、javadocを出力する際にjavadocコマンドを指定するが、そのjavadocコマンドのJavaバージョンと、プロジェクトのJavaバージョンが違っていた。
これを、プロジェクトのJavaバージョンのjavadocコマンドを指定するように修正するとエラーが発生しなくなった。

## プログラム格納フォルダに日本語
コメントにて、プログラム格納フォルダに日本語を含む場合も同じエラーになるとの情報がありました。

# あとがき
こんなことは当たり前過ぎるかもしれないが、古いJavaバージョンのJavaプロジェクトの修正等を最新のeclipseでやろうとした場合はjavadocコマンドがデフォルトで最新のJDKで設定されているため、盲点だった。
Laravel +Vagrant + CentOS環境でphp artisan migrate時のcould not find driverエラーの解決方法

#事象
**could not find driver**、ドライバーがないよと怒られる。

経緯としては、Homesteadでの環境構築の利用ではないLaravel環境構築後にて(CentOS利用)Todoアプリを作成中**php artisan migrate実行時に以下のエラー出現**

```bash
$ php artisan migrate

   Illuminate\Database\QueryException  : could not find driver (SQL: select * from information_schema.tables where table_schema = laravel and table_name = migrations and table_type = 'BASE TABLE')

  at /vendor/laravel/framework/src/Illuminate/Database/Connection.php:669
    665|         // If an exception occurs when attempting to run a query, we'll format the error
    666|         // message to include the bindings with SQL, which will make this exception a
    667|         // lot more helpful to the developer instead of just the database's errors.
    668|         catch (Exception $e) {
  > 669|             throw new QueryException(
    670|                 $query, $this->prepareBindings($bindings), $e
    671|             );
    672|         }
    673|

  Exception trace:

  1   PDOException::("could not find driver")
      /vendor/laravel/framework/src/Illuminate/Database/Connectors/Connector.php:70

  Please use the argument -v to see more details.
```

###環境情報

|name|version |
|---|---|
|CentOS|7.5.1804|
|Vagrant|2.2.6|
|VirtualBox|6.0.16|
|Laravel|6.12.0|
|PHP|7.4|
|Windows|10|

※2020/02/16時点



##原因

**PHPのモジュールにMySQLのドライバ(php-mysqlnd)が入っていなかった。**

私の凡ミスだがPHPモジュールにMySQLのドライバを入れ忘れていた。

##解決策

###1.モジュール確認
PHPにMySQLのドライバがいるか確認
pdo_mysqlがいればOK

```bash
$ php -m | grep pdo
pdo_sqlite
```

sqlite用のドライバしかいない

###2.php-mysqlndをインストール
yum installにて　PHPのMySQLドライバ、『php-mysqlnd』をインストール
※remiリポジトリ使っていたのでremiもインストール

```bash
$ sudo yum -y install --enablerepo=remi,remi-php74 php-mysqlnd
Loaded plugins: fastestmirror
~~~~~~~以下省略~~~~~~~
```


###3.確認

```bash
$ php -m | grep pdo
pdo_mysql
pdo_sqlite
```

**確認できたのでApacheを再起動**

```bash
$ sudo service httpd restart
```

artisanコマンド実行

```bash
$ php artisan migrate
Migration table created successfully.
Migrating: 2020_02_15_150504_create_posts_table
Migrated:  2020_02_15_150504_create_posts_table (0 seconds)
```

解決

#結論
**MySQLをインストール時、PHPのMySQLモジュールのインストールも忘れずに**


###参考サイト
[【Laravel】CentOSのLAMP環境でcould not find driver](https://www.suzu6.net/posts/198-could-not-find-driver/)
RailsでスコープとGraphQL::Batch::Loaderを使うときの注意点

RailsでGraphQL::Batch::Loaderを使うときの注意点です。

## 問題

N + 1問題を回避しようとしてGraphQL::Batch::Loaderを導入したが、N + 1問題が回避されなかった。

GraphQL::Batch::Loaderは以下のように、N + 1問題を回避するためのクラスです。
https://github.com/Shopify/graphql-batch#schema-configuration

## 原因

GraphQL::Batch::Loaderのforの引数にスコープ(ActiveRecord::Relation)を渡していたことが原因です。

GraphQL::Batch::Loaderでは、forの引数が同じ場合にBatch Loadされます。

同じというのは正確には、ハッシュのキーとして一致するという意味です。
ActiveRecord::Relationはハッシュのキーとして使えるように実装されていないので、実質的に同じでもハッシュのキーとして一致することはありません。

そのため、同じと認識されずBatch Loadされない。

## 解決策

ActiveRecord::Relationをハッシュのキーとして使えるようにするために、
以下のモンキーパッチを当てました。

```ruby
module ActiveRecord
  class Relation
    def hash
      to_sql.hash
    end

    def eql?(other)
      self == other
    end
  end
end
```

Railsで実装検討されたこともあったみたいですが、放置されていました。
https://github.com/rails/rails/pull/33638
GitのコミットコメントとGithubのissueを紐づけてタスク管理する

個人開発する際に，タスク管理のため行っているissueとbranchの紐付け方法のメモ．
### Gitでコミットする時にissueの番号をコミットコメントにする
例を挙げると

```
git commit -m "#8"
```
とすると,codeのコメント欄ににissue番号#8に対してのリンクが付与されていることが確認できる．

コミットコメントに番号が含まれてさえいればいいので，下記のような形でもOK．

```
git commit -m "#8 削除機能実装"
```
これを利用して,１日から数時間程度で終わるぐらいの分量でissueを作成し，各issueごとにbranchを切って作業するとよい．
### タスク管理の流れ
1. issue作る
2. issueひとつに対しひとつブランチ切る（ブランチ名もissue番号にしてしまうのがおすすめ）
3. 作業する
4. コミットする(右のコマンドでissue閉じながらコミットできる)
```
git commit -m "hoge create close #8"
```
REST API（Integration Architecutre デザイナー）

# REST API
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/577032/276163a8-f30a-7267-efa3-db32529dcbaf.png)

## 特徴
- リモートサイトからSalesforce標準APIを呼び出す為の**インバウンド連携**
- 設計パターンの「**リモートプロセス呼び出し－要求と応答（同期処理）**」に該当する
- Salesforceが提供する**標準API**を利用する為、仕様に基づけば即時連携が可能となる
- **URI**で操作対象のリソースを表現して、リソースに対するCRUDを**HTTPメソッド**で実現する
- HTTPメソッド毎のリソース操作
 - **GET：リソースの取得：SELECT**
 - **POST：リソースの作成：INSERT**
 - **PATCH：リソースの更新：UPDATE**
 - **DELETE：リソースの削除：DELETE**
 - **PUT：リソースの作成または更新：UPSERT**
- 認証は主に**oAuth2.0（access_token）**であり、セッションIDも可
- 返却形式は主に**JSON**であり、XMLも可
 - JSONの場合、**ペイロードが軽量**である
- 接続したいデータの用途によりRESTベースのAPIが異なる場合がある
 - Chatter：Chatter API
 - メタデータ：メタデータ API
 - Force.com アプリケーション用のカスタム開発ツール：Tooling API 


## セキュリティ
- データ
 - ログイン時のユーザに対応したSalesforce側のデータセキュリティが働く（オブジェクト権限、項目レベルセキュリティなど）
- ネットワーク
 - **TLS**プロトコルが必須 
 - Salesforceネットワーク認証により接続可能な時間帯、プロファイルまたは組織全体でのIPアドレス範囲の制御が可能

## サンプル

### GET（query）
``` 
/vXX.X/query/?q=SOQL クエリ
/vXX.X/query/?q=SELECT+id+,+Name+FROM+Lead+limit+1
```

## 注意すべきガバナ制限
|制限|備考|
|:------------------|:------------------|
|24 時間あたりの合計コール数|[エディション毎の計算方法](https://developer.salesforce.com/docs/atlas.ja-jp.salesforce_app_limits_cheatsheet.meta/salesforce_app_limits_cheatsheet/salesforce_app_limits_platform_api.htm)|
|1 つの SOSL クエリによって取得されるレコードの合計数2000件||

## RESTを選択するシナリオ
- モバイル、タブレット等のネイティブアプリケーションとの連携が必要な場合（軽量の為）
- 少数のレコード件数の登録・更新・削除の場合
- カスタマイズされたChatter、コミュニティまたはおすすめ用の UI を構築する場合
 - Chatter REST API を使用

## リファレンス
- [REST APIドキュメント](https://developer.salesforce.com/docs/atlas.ja-jp.api_rest.meta/api_rest/intro_what_is_rest_api.htm)
MATLABでGitを操作しよう (第3回 : チェックアウト "特定のコミットに戻る")

引き続きMATLAB GUIによるGit操作の第3回目

作成環境 MATLAB R2019b

[第1回 : プロジェクト作成とGUIの説明](https://qiita.com/stozaki/items/e4fa14c36f6c134e53e7)
[第2回 : git add/git commit](https://qiita.com/stozaki/items/4bacb2e988c74f7a16e4)
**第3回 : チェックアウト "特定のコミットに戻る"**
第4回 : ブランチ作成
第5回 : リモートリポジトリとの連携 (git push/git pull)
第6回 : クローンを作成する
第7回 : 応用1
第8回 : 応用2

よく見たら、チェックアウトが抜けていたので、今回はチェックアウト。次回ブランチ作成とさせて頂きます。また、次回はMATLABのAPIを使ってGitとどの様な連携が取れるのか？も紹介予定です。

# チェックアウト
① : 特定のコミットに戻る
② : ブランチの切り替え
前者は、「**覆水盆に返す**」とでも言いましょうか、今回紹介します。
簡単に図示すると次の様なことをMATLAB GUIで実施してみます。
![git3_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/023753d0-6665-e6a4-c707-d8924e233db5.png)

 
#### 1.ファイルを更新してコミットを繰り返す
準備として先ず、foo.mとgoofy.mがリポジトリにコミットされている所から話を始めます。
![git3_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/e58801dd-e821-0b56-b544-d42e5fd4ba3d.png)

ここでgoofy.mのファイルを開いてみます。(単なるコメント文のみです)
![git3_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/eff997fb-4d70-02c5-8934-871189e374ed.png)

次にgoofy.mを編集します。
![git3_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/822285c4-1292-d8de-3475-47fdf06417e0.png)

Gitのステータスアイコンが青い四角に変わったので、トラッキングしているファイルに変更があったことを意味しています。
![git3_4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/3d71b061-50a5-818b-a54d-2b40717965fc.png)

コミットコメントをシンプルに書いて、コミットを実行します。
![git3_5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/85748cf7-cfac-2f99-72a6-6d017bc46966.png)


再度、goofy.mを編集し、コミットを行います。
![git3_6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/f889c7d0-cf5e-f8f8-d877-23608f991af3.png)

ここまでで、goofy.mは2回変更があったことが、コミットされているはずです。
そこで、「ブランチ」アイコンをクリックしてコミット履歴を確認してみます。
![git3_7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/c9fe1b13-72b1-7e0e-b5b2-067958aa5c12.png)

#### 2.チェックアウト(過去のコミットに戻る)
ブランチブラウザを閉じて、プロジェクトウィンドウで対象となるgoofy.mを右クリックします。
コンテキストメニューから「ソース管理」> 「Gitを使用して元に戻す」をクリックします。
![git3_8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/1c36c94d-e7a3-f08b-66c8-4f6de20127b3.png)

「ファイルを元に戻す」というウィンドウが起動します。
過去のコミットポイントが一覧で表示されるので、戻したいコミットポイントを選択して、「元に戻す」をクリックします。今回は一番最初の状態に戻してみます。
![git3_9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/a915a1f1-946c-ac79-9c3f-103f8c6d8f15.png)

goofy.mを開くと、無事に最初の状態に戻っていました。
![git3_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/22ee9681-e37b-2339-8e04-0ec30075caa9.png)

#### 3.差分確認
最後に、MATLABの差分ツールを使って、テキストの差分を見てみます。
goofy.mを右クリックし「比較」> 「先祖と比較」をクリックします。

![git3_11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/a7c64276-5ad3-8b04-7acc-f3d8bfe29ccf.png)

確かに、チェックアウトしている状態のファイルと最新の状態のファイルのテキスト差分をちゃんと認識していることを確認出来ました。
![git3_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324583/bd6d7b17-49b6-921b-de14-b371354a814d.png)



誤解の無いように補足すると、Gitはコミット毎にスナップショットを保存しており、ファイル差分を保存しておりません。スナップショット内のファイルからテキストデータを抽出してテキスト差分を表示しています。
Streaming API（Integration Architecutre デザイナー）

# Streaming API

## 特徴
- **Publish/Subscribe（公開/登録）**モデル
- **PushTopic**、**汎用ストリーミング**、**プラットフォームイベント**、**変更データキャプチャ**に分類される [参考ページ](https://developer.salesforce.com/docs/atlas.ja-jp.api_streaming.meta/api_streaming/event_comparison.htm)

### PushTopic
- 設計パターンの「**データの変更に基づくUIの更新**」に該当する
- Salesforceとクライアント間の接続をポーリングする為に**Bayeuxプロトコル**を実装した**CometD**を利用する
- Publish側は公開用チャネルの**PushTopic**オブジェクトにレコードを作成する
- Publish/Subscribe間で**ロングポーリング**を行う事で**セッション維持**と**通知の確認**を行っている
- クライアントは**外部クライアント**または**Salesforce内のページ**
 - 外部クライアントはCometDのライブラリを利用して実装する必要がある
 - Salesforce内のページは[Visualforce](https://developer.salesforce.com/docs/atlas.ja-jp.api_streaming.meta/api_streaming/code_sample_generic_vfp_intro.htm)または[LWC](https://developer.salesforce.com/docs/atlas.ja-jp.api_streaming.meta/api_streaming/code_sample_lightning_cmp.htm) 
- ロングポーリングの通知結果でSubscribe側がPublishであるSalesforce側からデータを取得する場合、**ストリーミングAPIイベント数**がカウントされる（ポーリング時はカウント対象外）
- 通知内容は1日キューイングされる
- **再送**や**通知**を**保証しない**（UDPみたい）
 - 外部クライアントが通知内容を再取得したい場合はCometD経由でReplayIdを指定する事で再取得可能

### 汎用ストリーミング
- **Salesforce内のデータ変更に関連しない通知**を行いたい場合に利用する

### プラットフォームイベント
- 「**リモートプロセスの呼び出しーファイアアンドフォーゲット**」に該当する設計パターン
- **Salesforce内外**（内部だけではなく外部からも通知可能！）からイベント通知を行う仕組み
　こちらの[ページ](https://developer.salesforce.com/blogs/2019/07/a-refresher-on-the-four-streaming-apis-and-a-monitoring-tool.html)の図が非常に分かり易い
- Salesforce内としては**プロセスビルダー**や**フロー**からも通知可能

### コード（PushTopic)
```java
PushTopic topic = new PushTopic();
topic.Name = 'Architecuter News';
topic.NotifyForOperationCreate = true;
topic.NotifyForOperationUpdate = true;
topic.NotifyForOperationDelete = true;
topic.Query =  'SELECT Name From Lead Where Company= \'Salesforce\'';
topic.NotifyForFields = 'All';
insert topic;
```
### 通知されるまでの流れ
以下の3条件が全て満たされる場合に通知される
1. レコードが更新　かつ
2. NotifyForFiledsを満たす場合　かつ
3. QueryのWhere句の条件が一致する場合

### Query項目
- チャネルへの送信をトリガするレコードへの変更を特定するSOQLクエリステートメント
 - リレーション名などでの項目はサポート外

### NotifyForFields項目
| 選択値 | 説明 | 備考 |
| --- | --- | ---|
| All | レコードのいずれかの項目が更新された場合 | NameまたはCompany|
| Referenced | Select句、Where句で使用されている項目のどれかが更新されたら場合 | NameまたはCompany|
| Select | Select句で使用されている項目のどれかが更新されたら場合 | Name |
| Where | Where句で使用されている項目のどれかが更新されたら場合 | Company |

## Streaming APIを選択するシナリオ
- 準リアルタイムで他システムにSalesforceデータの変更を教えたい場合
 - ただし確実に通知させるほどではない場合（スマホのYoutubeチャンネルの新規投稿通知みないな感じ）

## リファレンス
- [CometD](https://cometd.org/)
- [Streaming APIドキュメント](https://developer.salesforce.com/docs/atlas.ja-jp.224.0.api_streaming.meta/api_streaming/intro_stream.htm)
C#でSTLのバイナリを読み込む

某言語のライブラリじゃないやつ。

## ソースコード

```C#
static Vector3f[][] LoadStlFile(Stream stream)
{
    byte[] buff = new byte[84];

    stream.Read(buff, 0, 84);
    string anyText = Encoding.ASCII.GetString(buff, 0, 80);
    int numOfPolygon = BitConverter.ToInt32(buff, 80);

    Vector3f[][] polygons = new Vector3f[numOfPolygon][];

    for (int i = 0; i < numOfPolygon; i++)
    {
        stream.Read(buff, 0, 50);

        polygons[i] = new Vector3f[3]
        {
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 3),
                BitConverter.ToSingle(buff, 4 * 4),
                BitConverter.ToSingle(buff, 4 * 5)),
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 6),
                BitConverter.ToSingle(buff, 4 * 7),
                BitConverter.ToSingle(buff, 4 * 8)),
            new Vector3f(
                BitConverter.ToSingle(buff, 4 * 9),
                BitConverter.ToSingle(buff, 4 * 10),
                BitConverter.ToSingle(buff, 4 * 11)),
        };
    }

    return (polygons);
}

static Vector3f[][] LoadStlFile(string path)
{
    using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read))
    {
        return (LoadStlFile(fs));
    }
}
```

`任意の文字列`と`法線ベクトル`は読み捨ててます。
戻り値は頂点のジャグ配列ですが、環境に合わせて煮るなり焼くなり好きにしろ。
エラーチェックとか一切やってないので気をつけてね。

## 参考

[STLファイルフォーマット](https://www.hiramine.com/programming/3dmodelfileformat/stlfileformat.html)

## 感想

なにゆえ1ポリ50バイト? 48ポリのほうがスッキリする気がする。