OmniAICreator/Qiita-1.07M huggingface dataset:
PythonのOpenCVで VideoCapture 関数が動画ファイルを読み込んでくれない

pythonのopencvで動画ファイルを読み込んでなにやらしようとしたら、動画ファイルを読み込んでくれなかった。

```
(pythonファイル内)
cap = cv2.VideoCapture(video_path)
while True:
    ret, img = cap.read()
    # あとは img 好きなように...

(実行時の出力)
OpenCV: Couldn't read video stream from file "*****"
```

いろいろ調べたところ、よく出る解決策が `skvideo.io` をimportして使え、というもの。

言われるがままにやってみた。

まず、`pip`でインストール

```
(以下を実行)
pip install sk-video
```

そして、pythonのソースコード

```
import skvideo.io #追加

#cap = cv2.VideoCapture(video_path) ← 削除

reader = skvideo.io.FFmpegReader(video_path) #追加


#while True:  ←　削除
#    ret, img = cap.read() ← 削除　　

for img in reader.nextFrame(): #追加
    #あとは img を好きなように...
    
```

これで動きました。
上のコードでいう`ret`が取得できていませんが、都合の悪い人はすみませんが調べてみてください...

python
python3
skvideo.io
opencv
OpenCV: Couldn't read video stream from file
ShaderLab 移動・回転・拡縮コード

# 内容
・移動・回転・拡縮のコードを書きます
　→資料が見つからなかったのでメモ

# 環境
・Unity5.4
・Windows

※間違っていたら指摘ください

# 初期準備
・UI-Default.shaderをベースに使用する
 →Unityビルドインシェーダー

# パターン
## 移動
```
//OUT.texcoord = IN.texcoord; // 元々書かれていたコード
OUT.texcoord = IN.texcoord;
OUT.texcoord.x += _Time.y; // 横方向へスクロール
OUT.texcoord.y += _Time.y; // 縦方向へスクロール
```
[画像を後で貼り付ける]

## 回転
```
//OUT.texcoord = IN.texcoord; // 元々書かれていたコード
// 回転を設定
float angle = _Time.y * 1.0;
// 回転行列
float2x2 rotate = float2x2(cos(angle), -sin(angle), sin(angle), cos(angle));
// サイズを設定
float scale = 0.5;
// 回転UVを設定
float2 pivot_uv = float2(0.5, 0.5);
float2 r = (IN.texcoord.xy - pivot_uv) * (1 / scale);
OUT.texcoord = mul(rotate, r) + pivot_uv;
```
[画像を後で貼り付ける]

## 拡大・縮小
```
//OUT.texcoord = IN.texcoord; // 元々書かれていたコード
// サイズを設定
float scale = _Time.y % 1.0;
// 中心UVを設定
float2 pivot_uv = float2(0.5, 0.5); // ←UV方向間違ってる？
float2 r = (IN.texcoord.xy - pivot_uv) * (1 / scale);
OUT.texcoord = r + pivot_uv;
```
[画像を後で貼り付ける]

# お世話になった書籍・サイト
＜Unityシェーダープログラミングの教科書 ShaderLab言語解説編＞超オススメ！！
・https://s-games.booth.pm/items/660001
＜サイト＞
・https://qiita.com/niusounds/items/cb821062acfd353d088d
Rubyのfaradayを使ってslackにsnippetを投下する

# やりたいこと
- slack botからddlをsnippetで投下
- snippetの設定言語をsqlに設定していい感じに
- 折りたたんだ状態で投下する(できなかった...)

# 現状
- メッセージに\`\`\`を入れて`コード`として認識させる
- 折りたたまれず見た目が悪い
- あまりにddlが長いと分割されてコードと認識されない

# やり方
- slack apiのfiles.uploadを使用
- modeでsnippetを指定（デフォでsnippetだったので省略）
- まずcurl文で検証

```hello_snippet.sh
curl -F channels={CHANNEL_NAME} -F content="Hello snippet" -F token={SLACK_TOKEN} https:/
/slack.com/api/files.upload
```

-次にfaradayを使ってPOST

```hello_snippet.rb
require 'faraday'
require 'json'

slack_uri="https://slack.com/api/files.upload"
conn = Faraday::Connection.new(:url => slack_uri) do |builder|
  builder.request  :url_encoded     # リクエストパラメータを URL エンコードする
  #builder.response :logger          # リクエストを標準出力に出力する
  builder.adapter  :net_http        # Net/HTTP をアダプターに使う
end

res = conn.post do |req|
  req.body = {
    "title"=>"Hello snippet",
    "filetype"=>"sql",
    "token"=>SLACK_TOKEN,
    "channels"=>CHANNEL_NAME,
    "content"=>"Hello snippet"
  }
end

puts JSON.load(res.body)['ok']
```

# 結果
- いい感じに投稿できました
- デフォルトで折りたたむのはできませんでした...
<img width="1048" alt="スクリーンショット 2017-10-24 16.51.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/198985/f573e327-cffb-ac82-0dd9-7485a38a448a.png">


# 参考にしたページ
- https://github.com/stevenosloan/slack-notifier/issues/63
- https://api.slack.com/methods/files.upload
VSCodeでopenFrameworksのプロジェクトをショートカットキー1発でbuild and runする


# XCode、卒業。
IDE的な補完機能は非常に便利だけど、ぱっと試したりそんなにメソッドを多用しない場合は重たいXCodeを使ってまで欲しいわけではないこともある。もうターミナルで `make` しちゃえという思想に至ったのでそうする。

バージョンはoF v0.9.8

## VSCodeのビルドタスク作成
oFのプロジェクトフォルダをvscodeで開いた状態で`Cmd + shift + B`すると、当然デフォルトでビルドタスクが無いので新しく作る。
以下の内容のjsonファイルを作成。

```json
// Author @JotaroUT
// easy build of openFrameworks project in vscode

{
    // See https://go.microsoft.com/fwlink/?LinkId=733558
    // for the documentation about the tasks.json format
    "version": "2.0.0",
    "tasks": [
        {
            "taskName": "Run",
            "command": "make; make RunRelease",
            "type": "shell",
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}
```

あとは`Cmd + shift + B`するだけ。ぁ〜超簡単。


### お気づきだろうか....
そう、単にterminalで`make`と`make RunRelease`しろと言ってるだけである。
実はopenFrameworksのプロジェクトをGenerateした段階でMakefileが作成されるため、`make`すると、「コンパイル終わったから`make RunRelease`するなりで実行してね」と言われる。

___`make RunRelease`の文言はバージョンによって異なるので注意されたし。適宜json変えるなりしてください。___
acts-as-taggable-onとRansackを使用したタグの複合検索

# やりたいこと
表題の通り**“acts-as-taggable-onとRansackを使用したタグの複合検索”**
複合検索とは、スペース区切りのAND検索を指します。
今回は、映像コンテンツに**type**というタグを付けて管理するという例で考えてみましょう。
同じようなことをする方は、少ないと思われますが、検索しても意外と結果が出てこないので、今後の方のために。
複合検索したいという場合は、modelの実装をすっ飛ばして実装すれば問題なく実装できるはず。
すこしRESTfulでないPathですが、ご勘弁ください。

# 最終実装
```ruby:app/models/Video.rb
class Video < ActiveRecord::Base
  acts_as_taggable_on :type
end
```

```ruby:app/controller/searches.rb
class SearchesController < ApplicationController

  def video
    groupings = []  # 空配列生成

    # パラメーターがあれば分割し、複数のAND条件分を生成する
    if params[:q].present?
      keywords = params[:q][:type_name_cont].split(/[\p{blank}\s]+/)
      keywords.each { |value| groupings.push(type_name_cont: value) }
    end

    # 生成したAND条件を検索する。初期の場合、全件出力
    @query = Video.ransack(
        combinator: 'and',
        groupings: groupings
    )

    @videos = @query.result(distinct: true)

  end

end
```

検索用のErbは以下のような感じ。

```erb:app/view/searches/video.htmk.erb
<%= search_form_for @query, url: searches_video_path, method: :post do |f| %>

    <!-- 検索窓 -->
    <div class="form-group">
      <label>フリーワード検索</label><br />
      <%= f.search_field :type_name_cont,
                         class: 'form-control',
                         value: params.dig(:q, :type_name_cont) %>
      <small class="help-block">※スペースで区切ることで複合検索ができます</small>
    </div>

<% end %>
```

```ruby:app/config/routes.rb
Rails.application.routes.draw do
  # 動画検索
  get 'searches/video' => 'searches#video'
  post 'searches/video' => 'searches#video'
end
```

## ポイント1
ネット上の記事では、tags_nameとなっているものが多いが…
ここではmodelで指定した**type**がデータベースでcontextとして扱われるためRansackの検索では、**type_name**と記述すること。
例えば、標準のままの**acts_as_taggable**だけの場合は、**tags_name**となる。

## ポイント2
ANDの複合検索のためにparams[:q]を再構築する。
再構築したものをRansackに代入する。
**combinator**を**or**にすると**or検索**となる

```ruby:app/controller/searches.rb
    # パラメーターがあれば分割し、複数のAND条件分を生成する
    if params[:q].present?
      keywords = params[:q][:type_name_cont].split(/[\p{blank}\s]+/)
      keywords.each { |value| groupings.push(type_name_cont: value) }
    end
```

## ポイント3
このままだと検索後に検索窓に結果が残らないという事態に遭遇するので、フォームの**value**に**params.dig**を指定する

## ポイント4
このままの実装だと、重複した結果が出力される可能性があるため、distinctを有効にする

# 最後に
ネット上のいろいろなサイトを潜りましたがなかなか良い回答が見つけにくかったので、残しておきます。
特にRansacを使用した複合検索をしたい方は、多いのではないでしょうか。
Android - ListView, ViewHolder and ConvertView

My memo.

Best practice. Let ConvertView set tag with ViewHolder then reused it instead of created.

http://blog.csdn.net/Bill_Ming/article/details/8817172
http://blog.csdn.net/xsf50717/article/details/49206385
http://www.cnblogs.com/xiangtailiang/p/3379543.html
http://julianchu.net/2015/09/26-implement-listview.html
コミュニティサイクルの利用履歴をスクレイピング v2

#はじめに
2016年5月に[コミュニティサイクルの利用履歴をスクレイピング](https://qiita.com/nuwaa/items/48c7e1588fb0409659ac)という記事を書きました。
あれから1年以上が経過し、そのときのスクリプトでは動作しなくなってしまいました。
そこで現在でも動作するようにしようと思い書き始めました。

#やってみたこと
今回もまずは、Python3 + BeautifulSoup4 + Selenium + Firefox で動作させます。
※最近のFirefoxをSeleniumと連携させるには[geckodriver](https://github.com/mozilla/geckodriver/releases)というのが必要です。

```docomo-cycle2.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

from selenium import webdriver
from selenium.webdriver.common.keys import Keys
import urllib.request
from bs4 import BeautifulSoup
import time
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.common.by import By
import csv

MEMBERID = "(自分のユーザID)"
PASSWORD = "(自分のパスワード)"

driver = webdriver.Firefox()
driver.get("https://tcc.docomo-cycle.jp/cycle/TYO/cs_web_main.php?AreaID=2")

mid = driver.find_element_by_name('MemberID')
mid.send_keys(MEMBERID)
password = driver.find_element_by_name('Password')
password.send_keys(PASSWORD)
password.send_keys(Keys.RETURN)

obj1 = WebDriverWait(driver,5).until(
    EC.presence_of_element_located((By.XPATH, "//*[@id='pc_bill']")))
obj1.click()

time.sleep(3)

data = driver.page_source.encode('utf-8')
soup = BeautifulSoup(data, "html.parser")

table = soup.findAll("table",{"class":"rnt_ref_table"})[0]
rows = table.findAll("tr")

csvFile = open("docomo-cycle2.csv", 'wt', newline='', encoding='utf-8')
writer = csv.writer(csvFile)
try:
  for row in rows:
    csvRow = []
    for cell in row.findAll(['td', 'th']):
      csvRow.append(cell.get_text().replace('\n',''))
    writer.writerow(csvRow)
finally:
  csvFile.close()


driver.close()
```
上記スクリプトを動かすと、docomo-cycle2.csvというファイルに利用履歴が出力されます。
Mac環境とWindows環境で動作確認済みです。

#今後のこと
実は、Headless Chrome向けのサンプルプログラムを作ろうとしたところ、どこで問題が発生しているのかが、Headlessだとわかりにくいため、Firefoxを使って人間の目で確認しつつデバッグしようと思い、この記事を書き始めました。
やっとこれでデバッグできたので、次はこのサンプルプログラムをHeadless Chromeで動かす場合の記事を書きたいと思います。
CWLで、cwlファイルをバリデーションする

# 概要

書いている最中の、 `cwl` ファイルのバリデーションをしたい。

# まとめ

schema_saladを使うとできる。

* [common-workflow-language/schema_salad: Semantic Annotations for Linked Avro Data](https://github.com/common-workflow-language/schema_salad)


`CommandLineTool` でも、 `Workflow` でも、次のコマンドで、バリデーション可能

```
schema-salad-tool /path/to/CommonWorkflowLanguage.yml target.cwl
```

# グラフを出力する

コメントでいただいので、サンプルを追記する（予定）

```
cwltool --print-dot
```

## 単純なコマンド出力例

TODO

## ２つのコマンドがつながっている、ワークフローの出力例

TODO

# 参考情報

Webで使える viewer

* [Common Workflow Language Viewer](https://view.commonwl.org/)

## ユーザローカルに最先端をいれる

pip install したあととか、versionを確認しておいたほうがよい。


```
pip install schema-salad --user
git clone https://github.com/common-workflow-language/schema_salad.git
cd schema_salad
python setup.py install --user
```

## debian sid の場合、

```
~/.local/bin/schema-salad-tool
```

に、インストールされていた

## Mac

以下のエラーがでている。

```
$ python setup.py install --user
error in schema-salad setup command: Invalid environment marker: python_version>="3"
```

## 開発版自分メモ

リロードは、コマンドパレットから、`Window Reload`
Vagrantでmount関連のエラーが出たときの対処法

#エラー
```
~/p/m/batch> vagrant reload
==> default: Attempting graceful shutdown of VM...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configuration...
    default: Adapter 1: nat
    default: Adapter 2: hostonly
==> default: Forwarding ports...
    default: 22 (guest) => 2216 (host) (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few minutes...
    default: SSH address: 127.0.0.1:2216
    default: SSH username: vagrant
    default: SSH auth method: private key
==> default: Machine booted and ready!
[default] GuestAdditions 5.1.20 running --- OK.
==> default: Checking for guest additions in VM...
==> default: Setting hostname...
==> default: Mounting shared folders...
    default: /vagrant => /Users/***/project/minshu/batch
Vagrant was unable to mount VirtualBox shared folders. This is usually
because the filesystem "vboxsf" is not available. This filesystem is
made available via the VirtualBox Guest Additions and kernel module.
Please verify that these guest additions are properly installed in the
guest. This is not a bug in Vagrant and is usually caused by a faulty
Vagrant box. For context, the command attempted was:

mount -t vboxsf -o uid=900,gid=1000 vagrant /vagrant

The error output from the command was:
```

上記のようなエラーが出る。

# 対処法
一旦インスタンスの中にsshして、symlinkを貼り直す。

```
~/p/m/batch> vagrant ssh
Last login: Tue Oct 24 16:06:13 2017 from 10.0.2.2

$ sudo rm /sbin/mount.vboxsf
$ sudo ln -s /usr/lib64/VBoxGuestAdditions/mount.vboxsf /sbin/
```

一旦exitして、reloadするとうまくいく。

```
~/p/m/batch> vagrant reload
```
Windows Mixed RealityでXboxコントローラーが動かない

#Xboxコントローラーを認識しない
Acerのモーションコントローラーが遅れているため仕方なくXboxコントローラーで始めたMR。
Holotoolkit-ExampleのXboxControllerExample.unityを実行した時のこと。
目の前に表示されたのは"No Controller Connected"の文字。

左スティックで移動、右スティックで視点移動はできるのに"No Controller Connected"が表示される。
USBを刺しなおしても反応は変わらず...。

運よく手元にXboxコントローラーが2つあるので、差し替えてみたら、あら不思議。

画面上に"A button:true B button: false"のように表示され始めた。

[![https://gyazo.com/31e30790b812111878f2f84dc33913c6](https://i.gyazo.com/31e30790b812111878f2f84dc33913c6.jpg)](https://gyazo.com/31e30790b812111878f2f84dc33913c6)

左が動いたやつ

#原因
[![https://gyazo.com/f4a287db814bfa60f7d7b48844819798](https://i.gyazo.com/f4a287db814bfa60f7d7b48844819798.png)](https://gyazo.com/f4a287db814bfa60f7d7b48844819798)

Xbox360のコントローラーでは動かないって感じかな？と。
ブラウザを開いたりする分には動いてたので残念(360の奴の方がXboxボタン押しやすいし)。

ドキュメントを読めば一発解決な問題だったので皆さんもドキュメントを読みましょう。
[Hololens・Windows MRのドキュメント](https://developer.microsoft.com/en-us/windows/mixed-reality/Hardware_accessories.html#bluetooth_gamepads)
MySQLのSQLで詰まったことまとめ

# 概要

MySQLにおいて詰まったことをここに入れていきます。
更新していく予定。
間違ったところがあれば指摘お願いします。

# AutoIncrement

## 0とNULL

### NO_AUTO_VALUE_ON_ZERO
#### **有効**

AUTO_INCREMENTカラムに0を挿入するとそのまま0が入り、nullを指定した時だけ採番された新しい数字が入る。

#### **無効**
nullまたは0のどちらでも新しい数字が採番される。

# Date型におけるトラブル

## DateDiff
### 「0000-00-00 00:00:00」 の検出

これを行うとすべからくNULLが返ってくる。
そのため、もし「0000-00-00 00:00:00」
の検出には、「IS NULL」を使う必要がある。


### 解決策
「IS NULL」を使うと検出できるのでそちらを使う。

ちなみに「0000-00-00 00:00:00」は
「IS NOT NULL」を使うと実は結果の中に入る。

以下のようなテーブルがあるとしたら

|id|data|
|:---:|:---:|
|    1 | NULL       |
|    2 | 0000-00-00 |
|    3 | 0000-00-00 |
|    4 | 2017-10-10 |
|    5 | 2017-10-05 |
|    6 | 2017-01-01 |

#### IS NULLの結果

|id|data|
|:---:|:---:|
|    1 | NULL |

#### IS NOT NULLの結果

|id|data|
|:---:|:---:|
|    2 | 0000-00-00 |
|    3 | 0000-00-00 |
|    4 | 2017-10-10 |
|    5 | 2017-10-05 |
|    6 | 2017-01-01 |



# 欲しいカラムの検出

データベースの中に欲しいカラムがあるのはわかっているが、テーブルがわからないときに利用できる。

```sql
select table_name, column_name from information_schema.columns
where column_name = '<検索したいカラム名>' and table_schema = '<検索対象のデータベース名>';
```

# データベースを指定するSQL
同じ構造のデータベースを複数持っている場合、データベースまで指定してSQLを実行することがある。その場合に困ったことを記述する。

## サブクエリについて
一つのサーバーに同じ構造のデータベースを複数乗せている場合に気をつける必要がありそう。

AとBの二つのデータベースがあるとする。
Aに向けたSQL(以下のSQL)をデータベースBをuseしている時に実行する場合

```sql:改善前SQL
SELECT COUNT(DISTINCT `name1`.`column`) AS tenpo_num
FROM `DB-A`.`table1` AS `name1`
INNER JOIN `DB-A`.`table2` AS `name2`
ON `name1`.`column` = `name2`.`column` 
WHERE EXISTS(SELECT * FROM `name1` WHERE `name1`.`column` <> 0)
```
これだとサブクエリのFROMで呼び出すテーブルがデータベースBのtable１になってしまう。
そのため、サブクエリでも明示的にデータベースAを指定してあげる必要がある。


```sql:改善後SQL
SELECT COUNT(DISTINCT `name1`.`column`) AS tenpo_num
FROM `DB-A`.`table1` AS `name1`
INNER JOIN `DB-A`.`table2` AS `name2`
ON `name1`.`column` = `name2`.`column` 
WHERE EXISTS(SELECT * FROM `DB-A`.`table1` AS `name1` WHERE `name1`.`column` <> 0)
```

# エラー編

## SQLSTATE[42000]: Syntax error or access violation: 1064 

そもそも発行したSQLに無理がある場合か、アクセス先の定義がされていない場合に呼び出される。

### 例 [フレームワーク]

CakePHPやZendframeworkなどのフレームワークにおいて
未定義のメソッドを使用しようとするとquery()メソッドが呼ばれ、
呼び出そうとしたメソッド名でクエリが発行される。


### 解決策

1. MySQLへのアクセスがうまくいっているかを確認
2. 発行されているSQL文自体に間違いがないかチェックし、修正 
3. フレームワークのクエリビルダーを使っている場合は、使用しようとしていたメソッドを記述間違い（名前間違い）などをチェックし、修正。


#### 1.  MySQLへのアクセスがうまくいっているかを確認

centosなどなら「/var/log/~」などにエラーのログが吐き出されているはずなので細かいところが画面に出力されていない時にはまずエラー文をチェックする。

また、mysqlコマンドにてmysqlにアクセスし、発行されているSQL文を実行して正常に実行できるかを確かめる。
できない場合は正常に実行できるSQL文に直し、それが実行されるようにソースコードを修正する。

#### 2. 発行されているSQL文自体に間違いがないかチェックし、修正 

しっかりと設計されていれば、発行されたSQL文のログが残っているはず。
そのSQLの部分をコピペし、Sequel Proでもなんでも良いので、実行してみる。

そこでうまく出力されないようなら、SQL文が間違っているため
それをうまく出力されるように変更し、等しいSQL文が発行されるように
ソースコードを修正する。


#### 3. フレームワークのクエリビルダーを使っている場合は、使用しようとしていたメソッドを記述間違い（名前間違い）などをチェックし、修正。

これは単純だが、そもそも記述間違いに気づいていない場合があるため、
パッケージやプラグインなどでこのような間違いが今後おきないようにするのが良いと考える。
mailxコマンドで本文と日本語ファイル名の添付ファイルを同時に送信する方法

日本語での資料が見当たらなかったのでメモも兼ねて投稿。

# 環境
（送信）Amazon Linux AMI release 2017.03
（受信）Mac/Win Gmail（Google Chrome）

# 元々のコマンド

`echo "メール本文"| mailx -s "メールタイトル" -a 日本語のファイル "mail@example.com"`

ここで `-a` オプションにPDF等のバイナリ形式のファイルを添付した場合、受信側でファイル名等が化けている事象が発生。

ファイルを渡すだけであれば標準入力から入れてやればよいが、今度は本文が入力できない状態に。

# 結果こうなりました。

`(uuencode 日本語のファイル 日本語のファイル; echo "メール本文") | mailx -s "メールタイトル" "mail@example.com"`

`uuencode` コマンドで対象のファイルをエンコードしたものの後にそのままメール本文をつけてやる。
こうすることで、ファイル名を文字化けさせずに本文と同時に添付ファイルを送信することが出来ました。

（参考）[Sending simple message body + file attachment using Linux Mailx](https://stackoverflow.com/questions/8314999/sending-simple-message-body-file-attachment-using-linux-mailx)
JUnit入門（勉強メモ）

※注：詳細な書き方については書いてありません。
Techscoreの[JUnitのページ](http://www.techscore.com/tech/Java/Others/JUnit/index/)をまとめただけです。
ユニットテストの書き方については[こちら](https://blog.tagbangers.co.jp/en/2017/10/23/junit-getting-started)をご参照ください（英語）
#ユニットテストとは
書いたコードが求められている通りに動作することを確認するためのテスト。
単体テストとも呼ばれる。
JUnitはJavaにおけるユニットテスト用の超有名フレームワーク。
みんなが共通のフレームワークを用いてテストプログラムを書くことで、他人のテストプログラムの修正が容易になる。
###テストの超基本的な流れ
１．テストするメソッドと同じ機能をもつテストメソッドを書く。
２．メソッドに求められる結果と、実際の結果をassertメソッド（下記）で比較する。
３．比較した結果相違があればテスト失敗、なければテスト成功。
###セットアップ（IntelliJ使用）
https://stackoverflow.com/questions/19330832/setting-up-junit-with-intellij-idea
https://www.slideshare.net/SatoshiKubo1/junitjava


#assertメソッドの種類
テストの結果の確認には、様々はassertを用いる。
###assertEquals()
→　期待される結果と実際の結果が同じかどうか判定する。
引数１：(expected, actual)
引数２：(String message, expected, actual) - テストが失敗した場合にmessageが表示される。
引数３：(expected, actual, delta) - deltaは許容誤差。
引数４：(String message, double expected, double actual, double delta) - 
###assertNotNull() 
→　与えられたObjectがnullでないかどうか判断する。
引数１：(Object object)
引数２：(String message, Object object) - テストが失敗した場合にmessageが表示される。
###assertNull() 
→　与えられたObjectがNullかどうか判断する。
引数１：(Object object)
引数２：(String message, Object object) - テストが失敗した場合にmessageが表示される。
###assertSame()
→　与えられた２つのObjectが同じObjectを参照しているか判断する。
引数１：(Object expected, Object actual)
引数２：(String message, Object object) - テストが失敗した場合にmessageが表示される。
###assertTrue() 
→　与えられた条件が正しいかどうか判断する。
引数１：(Object expected, Object actual)
引数２：(String message, Object object) - テストが失敗した場合にmessageが表示される。
###assertThat()
Matcherとの組み合わせで、assertEquals()より便利になる。
オブジェクトにequals()は一つしか作れないので、assertEquals()には限界がある。
検証をするのがassertThatではなくMatcherなので、拡張性も高い。何行もassertEqualsを書くという事態が起こらなくなる。
引数：(Object actual, Matcher matcher)　[詳細](https://qiita.com/opengl-8080/items/e57dab6e1fa5940850a3)

#注意点
##順序は関係ない
テストクラスの中のメソッドは、上から順に実行されるわけではない。
そのため、上のテスト結果を前提としたテストメソッドなどは書いてはいけない。
##副作用をつくらない
テストを行うとデータベースが更新される等、システムの状態を変えてしまう「副作用」を作ってはいけない。
##わかりやすいメソッド名をつける
後からコードを読む人がテストの目的をすぐに理解できるように。
##わかりやすいコードを書く
同上。無駄なくシンプルにわかりやすく。
##テスト計画はjavadocで書面化する
手動で書くのは面倒＋ミスも多い＋更新に追いつくのが大変。
##できるだけ小さく、早く
こまめに、気軽にテストを行えるために。

#その他便利なメソッド
複数のメソッドの中ではじめと終わりに共通の処理（データベースの接続・切断等）を行う場合は、setUp()とtearDown()メソッドを使うと良い。
###setUp()
各テストメソッドが呼び出される前に実行される。
###tearDown()
各テストメソッドの終了後に実行される。
###TestSuiteクラス
上記の通りテストメソッドは書いた順番どおりに実行されないが、TestSuiteクラスを使えばテストメソッドを実行する順番を指定できる。

#参考ソース
- [JUnit | Techscore](http://www.techscore.com/tech/Java/Others/JUnit/index/)
- [assertEqualsは古い | Java好き](http://javazuki.com/articles/assert-that-matcher-introduction.html)
- [ユニットテスト改善ガイド | Developers.IO](https://dev.classmethod.jp/testing/unittesting/working-effectively-with-unit-testing/)
- [これだけは覚えたい、ユニットテストを書くための４つのデザイン | Qiita](https://qiita.com/koduki/items/4fde43b68fe450c6a5d8)
- [HamcrestのMatchersに定義されているメソッドの使い方メモ | Qiita](https://qiita.com/opengl-8080/items/e57dab6e1fa5940850a3)
Heroku - error - Not a directory

#Not a directory Error when executing Heroku commands

```tcsh
heroku
 ▸    stat /Users/xxx/.local/share/heroku/client/bin/heroku: not a directory
 ▸    fork/exec /Users/xxx/.local/share/heroku/client/bin/heroku: not a directory

```
#Solution is to remove previous directory

```tcsh
rm -rf ~/.local/share/heroku/client
```
［iOS］UITableViewを活用したFontListアプリの作成

# UITableViewを活用したFontListアプリの作成
![スクリーンショット 2017-10-24 15.39.59.png](https://qiita-image-store.s3.amazonaws.com/0/199441/23324733-0ec6-5e44-b239-446c55fc4365.png)

## コード例
```swift:FontListViewCotroller.swift
//
//  FontListViewController.swift
//  FontList
//

import UIKit

class FontListViewController:UITableViewController{
    
    var fontName_array:[String] = []
    

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return fontName_array.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)
        let fontname = fontName_array[indexPath.row]
        cell.textLabel?.font = UIFont(name: fontname, size:20)
        cell.textLabel?.text = fontname
        return cell
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        for fontFamilyName in UIFont.familyNames{
            for fontName in UIFont.fontNames(forFamilyName:fontFamilyName){
                fontName_array.append(fontName)
            }
        }
    }
}
```
Android - Looper, Thread and Handler

Can't create handler inside thread that has not called Looper.prepare()

```
new Thread(){  
    Handler handler = null;  
    public void run() {  
        handler = new Handler();  
    };  
}.start();
```
1. One thread had the only one Looper and MessageQueue.
2. Threads exchanged data(message) via Handler.
3. You can also use "HandlerThread". It combined Thread, Looper and MessageQueue.
4. RxJava is the best solution to handle Android Thread.

http://blog.csdn.net/bboyfeiyu/article/details/38555547
http://mindtherobot.com/blog/159/android-guts-intro-to-loopers-and-handlers/
http://givemepass-blog.logdown.com/posts/296790-how-to-use-handlerthread
[Linux] 関数名からCライブラリを探すワンライナー


OSSだとそんなに困らないけど、プロプライエタリなソフトウェアの開発だとソースもドキュメントもなくてundefined reference出るけど関数がどのライブラリあるかわからないということがある。
そういう場合のためのワンライナー

例えば/optの下で関数hogehoge()を持つsoを探したい場合。

```bash
$ find /opt -name '*.so' | xargs -I'{}' sh -c 'f='{}'; nm $f 2>/dev/null | grep "T hogehoge" > /dev/null 2>&1; if [ $? -eq 0 ]; then echo $f; fi'
```
プログラミングに関するあの名前の由来 #2　言語名その2

#はじめに
17/10/24　リンク修正。指摘ありがとうございました。

[前回](https://qiita.com/yamato031033/items/6364f8078e233837c104)のがちょっと好評だったので、続きを書いていきます。
今回も、プログラミング言語の名前の由来を探っていきます。
今回は**C#,C++,Ruby,Swift**。

#C++
![cpp_logo.png](https://qiita-image-store.s3.amazonaws.com/0/205954/86482ae7-f41d-9529-b6d5-23cc8bb0a4f1.png)
**Cを1つインクリメントしたもの。**
++はc言語の演算子で、値を1つだけ増やす、という意味の記述。
拡張されたc言語という意味を、インクリメントで表現している。

**ボツ案：クラス付きのc**
cの拡張がクラスの追加に始まったから。
クラスはc++の心臓みたいな存在。
後に仮想関数や多重定義、テンプレートとか色々追加されていった。
しかし、Rick Mascittiという人の考えた「c++」は、
実にcの進化を表しているいい名前だと周りから評価されたので定着していった。
こっちの方が呼びやすいしね。

ちなみに名付け親のRick曰く、c++はふざけて考えた名前であり、ここまで普及するとは思ってなかったらしい

#C＃
![2p4i.png](https://qiita-image-store.s3.amazonaws.com/0/205954/87143634-fc39-3394-30a5-dd540154dce9.png)
**＋を4つ並べて＃。**
あたらしい言語の名前を考える会議みたいなのがあって、
音楽記号から適当に選んでつけた「C#」が候補に挙がっていたが、
誰かが「#って＋が並んでいるように見えるんじゃね？」って言ったら、みんなそう見えたらしい。
c++をさらに進めた形態にしようということで、**c++++**はどうかという提案も出たが、
c++++だと読みにくいので、＋を2*2で纏めたような記号＃を使った。
自分も＃の意味が気になってたのでこれは驚き＆納得。

**ボツ案：COOL (C like Object Oriented Language)**
C言語に似せたオブジェクト指向言語という意味。
オブジェクト指向なんてできないよ！って嘆いてたCプログラマを見かねた人が、
C言語とほとんど変わらないから大丈夫！と言葉巧みに騙して、
過酷な労働環境に放り込む意図があったとかなかったとか。
しかし、既にCOOLという名前の言語が存在したのでお蔵入りに。
他にも色々候補があって、
・Cs（Cセシウム）
・C2（Cスクエア）
・C3（Cキューブ）
…なんて名前になる可能性があった。

#Ruby
![Iruby.jpg](https://qiita-image-store.s3.amazonaws.com/0/205954/632c533d-4be4-c39e-1c34-ff99a9498942.jpeg)
**Rubyの生みの親まつもとゆきひろ氏の…同僚の誕生石（7月、ルビー）。**
なぜ自分の誕生石（4月、ダイヤモンド）にしなかったかは謎。
言語名は英語3~4文字がしっくりくるって、どこかに書いてたからそれで？
日本で開発された中では、初の国際規格に認証されました。

（追記17/10/24）
Rubyが生まれた当時、この分野を独占していたPerl（Pearl:真珠）を意識した名前付けではないかという意見をいただきました。
真珠も6月の誕生石ですからね。
Rubyの機能にも、Perlを強く意識したと伺える点が幾つかあります。　

#Swift
![Swift_logo.svg.png](https://qiita-image-store.s3.amazonaws.com/0/205954/620b2d73-c690-32e8-ed1e-5bc95ebc9403.png)
**迅速orアマツバメ。**
マークもツバメ（Swift）。
iOSとかMacのために、Appleが作った生まれたて（2014年）の言語。
アップル自身が掲げている強みの１つ、「**高速**な処理」とツバメをかけているのかも？
ASTERIA grepみたいな使い方

ASTERIA で部分一致・複数可変をマッチングするするのが意外と難しいです。

SQLの完全/部分一致と結合KEYの数が既知(=固定)/未知(=可変)の関係は,
下の表のようにまとめることが出来るかもしれません.

# SQLのマッチングのパターン

|  | 完全一致 | 部分一致 |
|:-----------:|:------------|:------------|
| 固定 | ①=演算とor | ②LIKE演算とor |
| 可変 | ③IN句 | ④SQL非対応 |


```SQL:社員マスタ
"織田信長"
"織田信忠"
"豊臣秀吉"
"豊臣秀頼"
"徳川家康"
"徳川秀忠"
```



## ①完全一致・固定のとき
普通にWHERE句を"="と "or"で取り出せますし.

```SQL:①
select
人名
FROM 社員マスタ A
WHERE  A.col1 = '織田信長'
or     A.col1 = '織田信忠' 

-- 
-- "織田信長"
-- "織田信忠"
```
orを使っているため,可変に対応していない.



## ②部分一致・固定のとき
LIKEとor を組み合わせでいける.

```SQL:②
SELECT
A.*
FROM 社員マスタ A
WHERE A.col1 LIKE　'%忠%'
or    A.col1 LIKE  '%秀%'　

-- 結果
-- "織田信忠"
-- "豊臣秀吉"
-- "豊臣秀頼"
-- "徳川秀忠"
```
orを使っているため,可変に対応していない.

ポイントはorが既知である.

## ③完全一致,・可変のとき
ちょっとせこいですが,
IN句の中を無理矢理でも文字列を整形,、
IN句の引数に代入することが出来れば,
query  = "('織田信長','織田信忠')"
可変長といえるでしょう.


```SQL:③
SELECT
A.*
FROM  A 
WHERE A.col1 in $query;  --  WHERE A.col in ('A','B')

-- 結果
-- "織田信長"
-- "織田信忠"
```

ポイントは, query = "('織田信長','織田信忠','豊臣秀吉')"
と"いくつでも"増やせすことが出来るところ.


## ④部分一致・可変のとき
これがSQLではできない.
僕が知らないだけからも知れない**(知ってる方がは教えてください)**


```SQL
-- これは文法的に間違っている
SELECT
A.*
FROM A
WHERE A.col1 in (%忠%,%秀%);


-- 結果は②と同じものを取り出したい.
```

IN句と%を同時に使用することができない.
[MYSQLでwhere句を、記述するときに、inと...]
(https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q1489805444)

### Linuxのgrep使えば,それほど難しいものではないよ
```bash
# 引数群をひとつのファイルにまとめる
cat arguments
忠
秀

vi sample.sh
cat arguments        |
while read $argument ; do
  grep $argument 会社マスタ
done

./sample.sh
# 結果
"織田信忠"     # 1回目のループ(=$argument="忠")の出力
"徳川秀忠"     # 1回目のループ(=$argument="忠")の出力  ★★★
"豊臣秀吉"     # 2回目のループ(=$argument="秀")の出力
"豊臣秀頼"     # 2回目のループ(=$argument="秀")の出力
"徳川秀忠"     # 2回目のループ(=$argument="秀")の出力 ★★★
```

★★★が被っているため,
SQLのDISTINCTに相当する処理をかます必要はあるものの,
argumentsファイルの中身が何行になっても対応できる点で可変である.

これはSQLでは出来ないの???

### 上記を, ASTERIAで実現してみる

#### ストリーム全体の流れ
![ETL-2017-10-24-1.png](https://qiita-image-store.s3.amazonaws.com/0/180419/a29cfb12-4bed-684e-a76a-49cf13d46d24.png)

##### ポイント
Linuxのソースコードとまったく同じく,
①argumentsファイルの方だけ, Loop処理
②argumentsファイルの中身をフロー変数(=argument)に格納
(このときストリームのままだと動かなかったので, 注意が必要である.)

#### Regexpコンポーネント 
Linuxのgrepに相当するのが,
ASTERIAでは Regexpコンポーネントを使う.
[ Regexpのヘルプ](http://stgetlweb01.infosys.cyberagent.local:21381/help/ja/flow/designer/index_function.html#REGEXP.html)
上記を覗くと
■備考のURLが死んでいるorz
また,入力が1つしかないパターンしか例が挙がっていない.

![ETL-2017-10-24-2.png](https://qiita-image-store.s3.amazonaws.com/0/180419/1a03d165-833a-55a9-6818-dc48005318c6.png)

Regexpコンポーネントの
入力1:社員マスタのcol1
入力2:フロー変数のargument
を指定.

Regexpコンポーネントの入力が２つ以上あるとき,
正規表現を書く必要がない**(むしろ書いたらダメ!!)**.→
入力2が”存在する場合、正規表現プロパティを置換”になるから。

##### 注意すべき点
特殊文字, たとえば, ),(などが入力2に含まれると,
エラーが発生するので,制御をかますことが本来必要かもしれない.

![ETL-2017-10-24-3.png](https://qiita-image-store.s3.amazonaws.com/0/180419/3334ba40-1d06-a3d0-8fb6-06461ff325c9.png)


# まとめ
④部分一致・可変に該当する抽出の仕方は, SQLが非対応のように
本来想定していない抽出の仕方だと思われる.
こうでないと取れない状況に遭遇したとき,
**データの構造が本来あるべき姿か**,
を見直すことをお勧めする.
あくまで,④は隠し芸程度に留めるべきだと私はおもう.
Fragmentで画面遷移する方法メモ

リファレンスによれば、
FragmentはActivityの中に配置し、いろいろなことに使えるそうだ。(ざっくり)

FragmentTransactionによって追加したり削除したり、表示したり非表示にしたり、などなどできるようだ。
FragmentTransactionはFragmentManagerを使って開始＆取得する。
FragmentManagerはActivityからgetFragmentManagerで取得できる。

アプリの初期化時にはaddを使ってFragmentを追加＆表示する。

```
        MainFragment fragment = MainFragment.newInstance();
        getFragmentManager().beginTransaction().add(R.id.container, fragment).commit();
```


File > New > Fragmentから追加したBlankFragmentを使ってMainFragmentクラスを作成すると、
MainActivityからaddした後、OnAttach内で例外を発生する。
onFragmentInteractionというメソッドを実装していないため。
MainActivity側で上記のメソッドを実装する。

```
public class MainActivity extends AppCompatActivity implements MainFragment.OnFragmentInteractionListener {

    @Override
    public void onFragmentInteraction(Uri uri) {
        // ここでFragment側で起きた何かをハンドリングする
    }
}
```
【Swift4】DEBUG時のみprint()でファイル名、行数、関数名を出力する方法

・[Swiftのprint()をファイル名、行数、関数名を出力して分かりやすくする](https://qiita.com/sotozaki/items/b2ed465dcf0ad6198a5f)

上記記事のコードをSwift4に対応し、DEBUG時のみ出力する形にいたしました。

```swift
func print(debug: Any = "", function: String = #function, file: String = #file, line: Int = #line) {
    #if DEBUG
        var filename: NSString = file as NSString
        filename = filename.lastPathComponent as NSString
        Swift.print("File: \(filename), Line: \(line), Func: \(function) \n\(debug)")
    #endif
}
```

使い方

```ViewController.swift
override func viewDidLoad() {
    super.viewDidLoad()
    print() // File: ViewController.swift, Line: 44, Func: viewDidLoad()
    print(debug: "テスト") // File: ViewController.swift, Line: 44, Func: viewDidLoad() テスト
}
```
Arraysクラスの asList の罠

# はじめに
最近、Arraysをよく使うことがあり、そのせいでハマったことがあるので
メモということで記します。

# 配列を作るには
Javaで配列を使用する場合、以下２つの方法がある。
new を使用して生成する場合と、ArraysクラスのasListを使って生成する方法。

- new ArrayList\<T>()

    ```java
    // 配列を生成
    List<String> hoge = new AraryList<String>();

    // 要素を追加
    hoge.add("test1");
    hoge.add("test2");
    ```

- Arrays.\<T>asList()

    ```java
    // 配列を生成
    List<String> hoge = Arrays.<String>asList("test1", "test2");
    ```

どちらも「test1」「test2」を持った文字列配列を作ることができます。

# 配列操作してみる
配列を作成したので、追加/編集/削除 を行ってみる。
テストコードはこんな感じ

```java:sample.java：Arraysを使ったケース
@Test
public void test_sample() {

    List<String> test = Arrays.<String>asList("aaa", "bbb");

    // 1.要素を追加
    test.add("ccc");

    // 2.要素を削除
    test.remove(1);

    // 3.要素を編集
    test.set(1, "ddd");

    // 4.要素を全クリア
    test.clear();
}
```

これを実行してみると、3のケース以外では
[java.lang.UnsupportedOperationException](https://docs.oracle.com/javase/jp/6/api/java/lang/UnsupportedOperationException.html)　が発生してしまいます。

では、new を使ったケースではどうか。

```java:sample2.java：newを使ったケース
@Test
public void test_sample2() {

    List<String> test = new ArrayList<>();
    test.add("aaa");
    test.add("bbb");

    // 1.要素を追加
    test.add("ccc");

    // 2.要素を削除
    test.remove(1);

    // 3.要素を編集
    test.set(1, "ddd");

    // 4.要素を全クリア
    test.clear();
}
```

こちらの場合、実行してもエラーが発生せず、以下のような結果となります。

1のケース後の配列の中身：aaa, bbb, ccc
2のケース後の配列の中身：aaa, ccc
3のケース後の配列の中身：aaa, ddd
4のケース後の配列の中身：空っぽ

# なぜか？
どちらも同じ配列操作をしているだけなのに、なぜ違いが出るのか。
new を使うと動的に配列を生成しますが、ArraysクラスのasListの場合

**固定サイズのリスト**　を返すからです。

JavaのAPI仕様書にも記載されていました。
[クラスArrays](https://docs.oracle.com/javase/jp/8/docs/api/java/util/Arrays.html)　より抜粋

| 修飾子と型 | メソッドの説明 |
|----------------------|-----------------------------------------------------------------------|
| static \<T> List\<T> | asList(T... a)<br>指定された配列に連動する<br>固定サイズのリストを返します | 


## 固定サイズのリストとは？
newを使った場合は指定要素のオブジェクトを
生成します。そのため**実体が存在します**。

しかし、Arrays.asListの場合、指定した
要素の内容を保持したリストのように
**見せかけているだけ**なので、固定サイズ(固定数)
のリストとなり、追加／削除といったリストの
数に関する操作を行うと、前述したようにUnsupportedOperationExceptionのエラーが発生してしまいます。

#まとめ
Arrays.asListで生成したリストは要素数の操作を
行うことはできないので、動的なリストを使った
処理には向きません(普通使わないと思いますが)

しかし、決まった要素数(変わり得ない)でリスト型で扱いたいときには、newで生成したオブジェクトにaddして行うよりも不用意なメモリを確保しないので個人的にはいいと思ってます。

※newで配列数を指定しないとデフォルトでは
10個分のメモリを確保してしまうので
StringやIntegerのようなものであれば
微々たるものかもですが、自前の大きなクラスの
場合だとチリも積もれば……ですので
Firefoxのコンソール出力画面でString.fromCharCode(160)【&nbsp;】が半角スペースになる 

# <i class="fa fa-cogs"></i> 検証環境

* Firefox 56
* Windows7
* Chrome 61


# 症状

たとえば

```html
<div>test&nbsp;test</div>
```

というHTMLがあった時、

```js
document.querySelector('div').innerText
```

には
`test (&nbsp;)test`
と格納されている。
これを

```js
console.log(document.querySelector('div').innerText)
```

とすると、出力は
`test (半角スペース)test`
になっている。

なので、一度コンソールに出力した結果をコピペし、生のinnerTextとコンソールで比較してみると

```js
document.querySelector('div').innerText === 'test test'
```
これはfalseになる。

コンソールの出力履歴に出たときに変換されるらしく、面白い現象が現れる。

![fxnbsp.gif](https://qiita-image-store.s3.amazonaws.com/0/62354/7b18f6dc-073c-7900-cdad-43b82b718409.gif)

一度trueになった式をコピペすると、falseになるのである。

なお、Chromeでは発生しなかった。

***

E2EテストでHeadlessChromeのテストコードとほぼ同じコードでFirefoxの開発者ツールで実行→コピペでexpectedコードを作成していたら、assertが通過しなかったことから発覚。

自動テストがChromeなら最初からChromeですればよかった…
next()とnextLine()の動作について

#Scannerクラスのnext()とnextLine()について
あれっと思ってしまったのメモしておく。

##next()の動作
next()はスペースで分割されたトークンを検索して、見つかった順にトークンを返します。
一度スキャナから入力を取り込んだ後にトークンを返すので改行うんぬんは関係ありません。

##nextLine()の動作
nextLine()は今あるカーソルを次の行の先頭に進めます。そして、スキップした分を出力します。


```java:java
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		String str = sc.next();
		String line = sc.nextLine();

		System.out.println(str);
		System.out.println(line);

		sc.close();
	}
}
```

上のコードに対して、下のような入力をした場合にどうなるでしょうか。

```java:入力
1
abcde
```

まず、sc.next()で一番最初のトークンが返されます。
strには1が入ります。
ここでカーソルは1と改行の間に来ます。

```java:入力
1[改行コード]
 ^
 ここ
abcde
```


ここで、sc.nextLine()を実行すると、次の行の先頭にカーソルが移動します。

```java:入力
1[改行コード]
 abcde
^
ここ
```
つまりnextLine()で読み込まれたのは改行コードのみとなります。

※間違っていたり不正確な内容でしたらご指摘ください。
AWSアカウント間のAMI共有

複数AWSルートアカウントを持っていて、一つ廃止したいです。
そこで作ったEC2インスタンスを移行（共有）する場合、AMIで簡単に実現できます。
手順として
####1．EC2インスタンスのイメージを作成
![image1.png](https://qiita-image-store.s3.amazonaws.com/0/191079/e4d87a1f-0a84-5565-46db-136aa5cb2264.png)

image nameを識別しやすい文言にして、「Create Image」ボタンをクリック
![image2.png](https://qiita-image-store.s3.amazonaws.com/0/191079/c0595609-e250-f552-13c4-531a540d696a.png)

####2．AMIの権限変更（共有先アカウントへ権限付与）
![imag3.png](https://qiita-image-store.s3.amazonaws.com/0/191079/a76d66d0-66e8-67f9-2e5f-5788ce56b437.png)
AWS Account Numberに12ケタの移行先AWSアカウント番号を入力し、「Add Permission」ボタンクリック
![image4.png](https://qiita-image-store.s3.amazonaws.com/0/191079/edfd36f2-332b-70ad-21eb-a358a7592615.png)
追加したら、同じポップアップ画面で確認ができます。
※create volume permissionsにチェックを入れると、AMIだけでなくsnapshotも共有されます。共有snapshotからEBSボリュームを作成することが可能です。
![image5.png](https://qiita-image-store.s3.amazonaws.com/0/191079/277206a8-a104-c853-c816-eeba4d32e4c0.png)
最後は「Save」して終わりです。

####3．共有先AWSアカウントでEC2インスタンスを作成
共有先のAWSアカウントでAWS Management Consoleにログインし、
EC2のインスタンス一覧画面で「Launch Instance」ボタンをクリック
AMI選択画面で、OwnershipをShare with meにちぇっくして、migrationで検索をかけると、
移行したインスタンスのAMIが表示されます。
いつもとおりにインスタンスを作成していけば完了となります。
![image6.png](https://qiita-image-store.s3.amazonaws.com/0/191079/a3e99a0a-c631-578b-4c17-86e2e7ec5bd1.png)
Assemble(grunt-assemble)の設定

# grunt-assembleの設定と動作　フロントエンド初心者向け
フロントエンド初心者には、grunt-assembleの設定と動作に関して混乱する場面が多かったので、[Assembleの使い方(Grunt task)](https://qiita.com/redamoon/items/aceb60e5be833b7e503f#%E4%B8%BB%E3%81%AA%E4%BD%BF%E3%81%84%E6%96%B9)に加える形で、備忘録がてら投稿致します。
## テンプレートエンジンとは
データとテンプレートに分けて管理することで、htmlファイルを分割的に生成する仕組み
つまり、文字列や画像を無視すれば、htmlを部分ごとに使いまわせるだろうという仕組み
## grunt-assembleの主な使い方

### htmlファイルになるまで
大きな流れとして、下記の順にファイルを読み込む事でhtmlファイルを生成すると考えてください。
1. テンプレートファイル(layout)
2. ページごとのファイル(files)
3. 場合によってパーシャル化されたファイル(partial)

テンプレートファイル：　bodyタグ内以外のテンプレート（head要素, header, footer, パーシャルhbsなど）
ページごとのファイル：　bodyタグ内（この中でパーシャルhbsを呼び出すことも可能）
パーシャル化：　htmlを分割してパーツとして扱うこと

※パーシャル化されたhbsは、テンプレートファイルでもページごとのファイルでも呼び出すことが可能
### Gruntfile.jsでの設定

```js
assemble: {
      options: {
        layoutdir: 'src/layout/',
        partials: 'src/include/**/*.hbs',
        data: 'src/**/*.json'
      },
      all: {
        options: {
          layout: 'default.hbs'
        },
        files: [
          {
            expand: true,
            cwd: 'src/html/',
            src: '**/*.hbs',
            dest: 'dist/'
          }
        ]
      }
    }
```

```
ディレクトリ構成
src
 ┃
 ┠html/　　ページごとのファイル
 ┠layout/　テンプレートファイル
 ┗include/ パーシャル化されたファイル
```

1. options: layoutdirに指定されたディレクトリ内のファイル（hbsファイル）をテンプレートとする。  
※ページごとのhbs上部にyml形式で指定すれば、テンプレートをページごとに変更できる  
※特に指定がなければ、all: options: layout: に指定されたhbsファイルが基本的なテンプレートとなる。
2. テンプレートhbs内の{{> body}}部分に、all: filesに指定されたディレクトリ（cwd:）配下のファイル（src:）が読み込まれる。    
※このcwd配下のhbsファイルの数だけ、htmlファイルが生成される。
3. htmlファイル生成先も指定（all: files: dest: ）


これらを理解できれば使用できるかと思います。
新しい元号への対応方法について（各社製品・部品の情報）

#Windows

```ps1:powershell
 (New-Object System.Globalization.JapaneseCalendar).eras.count
```

#Grapecity .NET 系
・CalendarGrid for Windows Forms 1.0J
・El Tabelle for .NET 3.0J
・El Tabelle MultiRow 4.0J
・El Tabelle Sheet 4.0J
・El Tabelle Sheet for Windows Forms 4.1J
・InputMan for .NET 3.0J
・InputMan for .NET Windows Forms 4.0J
・InputMan for Windows Forms 5.0J／6.0J／7.0J／8.0J／10.0J
・InputMan for .NET Web Forms 2.0J
・InputMan for ASP.NET 3.0J／7.0J／8.0J／10.0J
・InputMan for WPF 1.0J
・InputMan for Silverlight 1.0J
・MultiRow for Windows Forms 5.0J／6.0J／7.0J／8.0J／10.0J
・MultiRow for ASP.NET 1.0J
・PlusPak for Windows Forms 5.0J／6.0J／7.0J／8.0J／10.0J
・SPREAD for Windows Forms 5.0J／7.0J／8.0J／10.0J
・SPREAD for WPF 1.0J／2.0J
https://www.grapecity.com/tools/support/technical/knowledge_detail.asp?id=30516

----

##Component One
http://c1.grapecity.com/help/web/winforms/winforms_input/NewTopic6.html

----

##[Microsoft.TechNet]Japan New Era Name Support Blog   
日本マイクロソフトの新元号 (和暦) 対応に関するサポート情報のブログです
https://blogs.technet.microsoft.com/jperablog/
IBM Watson ConversationをSlackから叩いてみる

## はじめに
[Watson ConversationでLINEのチャットボットを作ってみる（後編）](https://qiita.com/KURO-BLACK/items/923830d259a5e12cad5b#_reference-e89944ac0639be7b66ff)という記事で、簡単なWatson Conversationの対話を作ってみました。今回はこれを、Slackbotとして活躍させてみます。仕組みとしては、Open Whisk(Function)という『イベント駆動型』のサービスが裏で動いています。リソースを占有せず動いた時だけ課金するという、注目の技術ですね。

## Workspaceの作成
上の記事を参考にして、Workspaceを作ってみてください。できるとこんな画面になります。
![IMG_0249.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/11f68fae-21a3-bb07-d744-9c681079b0ab.png)

## WorkspaceのDeploy
いきなりですが、左のメニュー、上から3つ目にあるDeployボタンを押してみます。
![IMG_0296.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/e1cf8aac-4881-f535-9573-bf1a29e5a973.png)

こんなのが出て入れば、Slackのところにある『Test in Slack』を押してください。
![IMG_0297.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/871d41df-7d42-1408-befd-fd4a2a136842.png)

## SlackのAuthorize
注意書きを読むと、Slack teamに許可を取る必要があると書かれています。『Authorize Slack』ボタンを押して、許可を取りましょう。
![IMG_0298.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/168ac654-91e6-a9f4-9303-2aeac8a5f908.png)

このブラウザで使っていた、自分のSlack teamが出てきました。『Authorize』を押してみます。
![IMG_0299.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/ed8b61e4-4ae6-9f15-2790-2df9a137f03a.png)

自動的に元いたDeployの画面に戻ってきました。Slack teamが表示されているので、承認された状態のようです。Step 2に書かれているのは、Slack teamのチャンネルでの使い方です。右にあるコマンドを使いたいチャンネルで使うと招待してくれますので、貼り付けて使いましょう。その前にまず、動作を確認してみますのでSlackのteamを開いてみます。
![IMG_0301.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/5a81f037-db52-35e8-1fd4-aba40855bd64.png)

## Slackでのテスト
Appsのところにibmwatson_botがいます。話しかけてみると、作ったWorkspaceが返事していることがわかりますね。
![IMG_0302.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/1e257d76-5596-7ffe-204b-a2369b369dcd.png)

generalのチャンネルに招待してみます。先ほどコピーして貼り付けるように言われた『/invite @ibmwatson_bot』をgeneralで発行して、挨拶を送りつけてみます。
![IMG_0304.PNG](https://qiita-image-store.s3.amazonaws.com/0/192662/6489177a-f623-b6eb-dd0a-50ba0c8997bf.png)

最初、返事が返ってこなくてキーってなりましたが、＠をつけて直接メッセージを送ることで返事がきました。こんな感じなんですね。

## おわりに
やっと、目的のWatsonまで記事が進みました。Open Whiskを勝手に動かしてくれるので、WatsonとSlackとの接続は本当に簡単でした。ただこのままだと生のConversationで拡張性がないので、最後まで書いて、ちょっとだけリッチなアプリケーションを目指したいと思います。

## 今後の計画
- [x] [まずはnode-redをBluemixで立ち上げます。無料枠で。](http://qiita.com/KURO-BLACK/items/77af2c98940320ca6ce9)
- [x] [Slackをただ繋げてみます。](http://qiita.com/KURO-BLACK/items/0cb3fac16c26876e5d00)
- [x] [IBM Watson ConversationをSlackから叩いてみます。](https://qiita.com/KURO-BLACK/items/95a70d203d5fc90fd980)
- [ ] node-redでSlackとConversationを接続してみます。
- [ ] Google Calendarに予定を投げて秘書に会議を設定してもらいます。
vccw で mailcatcher を起動時に立ち上げたい

# mailcatcher を vccw起動時に立ち上げたい
mail catcher を動かしたい
V3ではそのまま起動しているようで・・・汗[追記]
[Checking Email with MailCatcher](http://vccw.cc/#h2-6)
 
メールをローカルでテストしたいとなかなか思わなかったのでスルーしてきたんですが今回mailcatcherを使ってみたいと思って調べました。
[西村さんの投稿](https://private.hibou-web.com/archives/5987)をみて起動時に立ち上げるのがよいのね。と思って試していたんですが自分の環境ではすんなりいかなかったので備忘録。
西村さんありがとですー。

~~ohai をmac 上で動かす必要がある。~~
~~ohai はgem に入っている（chef-soloをinstallしたような気がするのでそのときに一緒にはいったのかな・・？）~~
~~PATHを通せば使える~~
~~ohai は rubyのver 2.1 以降で使える~~
~~ruby のverを変更する必要がある~~
~~ruby の現在のverは2.0.0 systemを見ている~~
~~ruby のverを管理するのはrbenvがよいらしい ~~
~~rbenvでrubyのverを変更する必要がある~~
~~rbenv のversionを変更したがrubyのversionはそのままなのでrbenv で管理するように設定~~

~~まだohaiのPATHが通っていないので修正~~

```
gem contents ohai | grep bin
/Users/lafcreate/.gem/ruby/2.3.0/gems/ohai-13.5.0/bin/ohai
```

```
vagrant ssh -c 'mailcatcher --http-ip=$(ohai | jq -r .network.interfaces.eth1.routes[0].src)'
```

を実行してみる。
nullが帰ってくる。・・・

MAC上ではなくてvccw上で必要だったことに気づく。

vccw上を確認する

```
vagrant ssh
```

してコマンドを走らせてみる。

```
ohai | jq -r .network.interfaces.eth1.routes[0].src
```

やっぱりnull
別々で試してみる。

```
ohai
```

ズララララ・・・・・・
これは動いていることを確認。

```
jq
```

コマンドが使えないみたいなことを言われる。
PATHを調べる。

```
ohai -v
which ohai 
/home/vagrant/.gem/ruby/2.3.0/bin/ohai
```

gem上にあることを確認

```
gem list
jq -h
which jq
/usr/bin/jq
```

jq は確認できたけど

ohai 、jqは元々vccwにinstallされているがjqはpathが通っていなかったので
（自分のやり方でどっかミスったのかわからないけども・・）

```
echo 'PATH=$PATH:$HOME/bin' >> ~/.bash_profile
```

```
ohai | jq -r .network.interfaces.eth1.routes[0].src
```

またnullが帰ってくる。
今度はohaiの中身を確認してみる。
長すぎて確認できないのでとりあえず適当にlogを残す。

```
ohai >> /vagrant/ohai.log
```

```
ohai | jq -r .network.interfaces.enp0s8.routes[0].src >> ohai-01.log
```

無事IPを取得できた。

```
vagrant ssh -c 'mailcatcher --http-ip=$(ohai | jq -r .network.interfaces.enp0s8.routes[0].src)'
```


とりあえずメモのまま貼り付け。
bootstrap v4 アルファなベータ

# bootstrap v4
現在（2017.10.24時点）で
[bootstrap v4 4.0.0.beta2](URL "https://getbootstrap.com/")がダウンロードできます。

# 結論
おいおい。
demoサイトは、アルファ（4.0.0 alpha）なのに、ダウンロードは 4.0.0.beta2やんけ～
まぁ細かいので放っておきましょう。

# 気をつけること
## alphaとbeta
demoサイトで、色々見て、ソースそコペピして表示させてみると、デモサイトと同様の表示にならないことがちらほら。
cssを見ると、alphaのdemoサイトで使われているclassが、betaのbootstrap.cssに無いやんけ～

- tooltip
- offset
- などなど

ダウンロードしたcssをマンマ使ったからかな・・・。
scssを活用するなら、話は違うのかも。

## デロリアン
xs関連のクラスが幾つかなくなってる。
どうやら思想が変わったのか、時代の流れなのか。

**デロリアンで来る前**
PC画面を表示して、スマホ用に表示をレスポンシブしてた

**デロリアンで来た後**
スマホが標準で、それを拡げたらどうなるかを考えながらレスポンシブする

みたいな感じですわ。


xsだよ、xs。重宝してたのに。
```
@media (min-width: 576px) 
  sm扱い
@media (min-width: 768px)
　md扱い
@media (min-width: 992px)
　lg扱い
@media (min-width: 1200px)
　xl扱い
```

※　デロリアン
伝説のタイムマシンですわ。
【AWS】Kinesis上のデータを取得するワンライナー【Kinesis Stream】

# はじめに
KinesisStream上のデータを直接確認したいケースがままあるため、ワンライナーをメモ。

KinesisStream上のデータを取得するには以下の2ステップが必要です。

1. Shard Iteratorを取得する
2. Shard Iteratorを利用して、getRecords APIを実行する

これを1行で行います。
取得対象データのSequence Numberが分かっていることを前提とします。
また、jqにパスが通っている必要があります。

# AWS CLIコマンド
## 基本パターン
```bash
$ aws kinesis get-records \
  --shard-iterator `aws kinesis get-shard-iterator \
    --stream-name [ストリーム名] \
    --shard-id [シャードID] \
    --shard-iterator-type AT_SEQUENCE_NUMBER \
    --starting-sequence-number [Sequence Number] \
    | jq ".ShardIterator"` \
  > output_file.json
```

## AWS CLIのプロファイルを指定する
get-shard-iterator及びget-recordsの実行時にそれぞれ同じプロファイルの指定が必要です。
うっかり一方にしか指定しなかった場合は、恐らく意図したデータは取れないでしょう。

```bash
$ aws kinesis get-records \
  --profile [プロファイル名] \
  --shard-iterator `aws kinesis get-shard-iterator \
    --stream-name [ストリーム名] \
    --shard-id [シャードID] \
    --shard-iterator-type AT_SEQUENCE_NUMBER \
    --starting-sequence-number [Sequence Number] \
    --profile [プロファイル名] \
    | jq ".ShardIterator"` \
  > output_file.json
```


## 取得したレコードを展開する
取得したデータは下記のようなJSON形式で保存されます。

```bash
$ cat output_file.json
{
  "Records":[ {
    "Data":"dGVzdGRhdGE=",
    "PartitionKey":"123”,
    "ApproximateArrivalTimestamp": 1.441215410867E9,
    "SequenceNumber":"49544985256907370027570885864065577703022652638596431874"
  },
  {
    "Data":"dGVzdGRhdGE=",
    "PartitionKey":"123",
    "ApproximateArrivalTimestamp": 1.441215410868E9,
    "SequenceNumber":"49544985256907370027570885864065577703022652638596431875"
  } ],
  "MillisBehindLatest":24000,
  "NextShardIterator":"AAAAAAAAAAEDOW3ugseWPE4503kqN1yN1UaodY8unE0sYslMUmC6lX9hlig5+t4RtZM0/tALfiI4QGjunVgJvQsjxjh2aLyxaAaPr+LaoENQ7eVs4EdYXgKyThTZGPcca2fVXYJWL3yafv9dsDwsYVedI66dbMZFC8rPMWc797zxQkv4pSKvPOZvrUIudb8UkH3VMzx58Is="
}
```

Sequence Numberを指定した場合、欲しいのは最初のレコードだけかと思いますので、下記のように切り出し、Base64デコードを行います。

```bash
$ cat output_file.json | jq --raw-output '.Records[0].Data' | base64 -d > output_file.bin
```

指定したSequence Numberに対応するレコードを取り出し、Base64デコードを行う場合は次のように指定します。

```bash
$ cat output_file.json | jq --raw-output '.Records[] | select(.SequenceNumber == "49544985256907370027570885864065577703022652638596431875") | .Data' \
  | base64 -d > output_file.bin
```

# 参照元資料
下記の公式ドキュメントからの焼き直しです。
すみません。

Perform Basic Stream Operations -> Step 3: Get the Record
http://docs.aws.amazon.com/streams/latest/dev/fundamental-stream.html#get-records


AWS APIレベルのドキュメントを併せて載せておきます。

GetShardIterator
http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetShardIterator.html

GetRecords
http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html
jqコマンドで特定のキーだけ抽出する

# tl;dr
ネストの深いJSONファイルも
jqで階層を指定してすれば
こわくない

# 背景
以下のような、だるいJSONから```updateKey``` の```value```を取り出したい

```
{
  "app": 1,
  "records": [
    {
      "updateKey": {
        "field": "setupdatekey",
        "value": "1"
      },
      "record": {
        "fieldName1": {
          "value": [
            {
              "id": "hoge",
              "value": {
                "fieldName2": {
                  "value": "foo"
                },
              }
            }
          ]
        }
      }
    },
    {
      "updateKey": {
        "field": "setupdatekey",
        "value": "2"
      },
      "record": {
        "fieldName1": {
          "value": [
            {
              "id": "fuga",
              "value": {
                "fieldName2": {
                  "value": "bar"
                },
              }
            }
          ]
        }
      }
    }
  ]
}
```
具体的には下記のような結果にして、ファイルに書き出したい。

```
"1"
"2"
```
# 方法
jqコマンドで階層を指定して出力すればよい。
上記の例の場合こんな感じ
```jq .records[].updateKey.value```


# 所感
JavaScriptとかでJSONを扱うときのように階層を指定することが、
jqでもできることが知らなかった。
ここから発展してワンライナーで色々とできそうだ。
ネストが深いJSONがきても、少しこわくなくなった。
Azure ロードバランサーのオフライン機能について

#概要
　[Azure ロードバランサー](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-overview)は、無償で提供されるレイヤー 4 (TCP、UDP) のロードバランサーです。この Azure ロードバランサーですが、現状ではオフライン機能を提供していないため、ロードバランサー配下のサーバーメンテナンスを実施する際に不便が生じるかと思われます。

　例えば運用管理者は、新規リクエストを止め、既存リクエストは中断させず処理を完了させた後にメンテナンス作業に入りたいという要望があるかと思います。このような場合、drain オフライン機能がロードバランサーに備わっていると簡単にグレースフルシャットダウンというかエラーなしでの切り離しが出来ます。

#代替え案
　ここではオフライン機能を代用する回避策として、セッション中断なくロードバランサー配下のサーバー (VM) を切り離す方法を２つ紹介します。

　何れの方法も Azure ロードバランサーがセッションを振り分けた後は、そのセッションをロードバランサー自らは切断しないという内部仕様を応用しています。これは Azure ロードバランサー経由で一度張られたセッションは、エンドポイントのサービス側もしくはクライアント端末側でセッションを切らない限り張られたままとなる事を意味します、Azure ロードバランサー自らが切断する事はありません。
###1. [カスタムプローブ](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-custom-probe-overview)のファイル名変更による切り離し
　Azure ロードバランサーは、常時 LB 配下のサーバーを死活監視しています。死活監視は TCP による特定ポートの監視、もしくは HTTP による特定ページの監視のいずれかを指定する事が可能です。負荷分散シナリオの多くは WEB サーバーが対象となるかと思われますが、この場合死活監視は特定の WEB ページを対象とする[カスタムプローブ](https://docs.microsoft.com/ja-jp/azure/load-balancer/load-balancer-custom-probe-overview)の利用が可能です。

　![probe.png](https://qiita-image-store.s3.amazonaws.com/0/166732/f4d1ade7-2761-1e20-2abb-0fe1f052db7c.png)

　カスタムプローブは、例えば /liveordead/probecheck.aspx のような特定の WEB ページを死活監視に指定します。そして、この該当ページへのプローブ呼び出しが 200 OK **以外**であった場合、Azure ロードバランサーは該当サーバーが異常であると判断し、サーバーをロードバランサー配下から切り離します。

　この仕様を逆手に取り、運用管理者はメンテナンスを実施したいサーバーの probecheck.aspx のファイル名をリネームする事で 404 エラーをプローブ監視に返す事が出来ます。これにより該当サーバーは新規リクエストを受け付けなくなりますが、既存のリクエストは張られたままとなります。しばらく時間をあけ既存リクエストが掃けてからサーバーのメンテナンスを実施します。メンテナンス完了後は、リネームしたファイル名を元に戻せば再度 LB の振り先として戻ってきます。
###2. バックエンドプールから外す
　WEB サーバー以外のサービス、例えば FTP, SMTP といったサービスを Azure ロードバランサーで負荷分散する場合ですが、この場合には HTTP プローブを利用できないため TCP によるサービスポートの死活監視が必要となります。例えば FTP であれば 20, 21 ポート、SMTP であれば 25 ポートがサービスポートであり、死活監視（プローブ）ポートでもあります。

　このような状況ではサービス（ポート）自体を止めないと死活監視（プローブ）による対象とならないので 1 のような手法はとれません。このため今回は Azure ロードバランサーのバックエンドプールから対象サーバーを削除するという方法を紹介します。

　![backendpool.png](https://qiita-image-store.s3.amazonaws.com/0/166732/66bf100e-73f3-c8ee-aa00-a84a516a5295.png)

　一見乱暴なやり方に見えますが、この場合でも既存セッションは切断されずに残ったままとなるため、削除処理により受け付けなくなるのは、それ以降の新規リクエストのみとなります。これにより削除処理が完了し暫く経った後にメンテナンスを実施する事でサービス中断をせずに該当サーバーを LB から切り離す事が可能となります。メンテナンス終了後は、バックエンドプールに再度追加する事で LB のメンバーとして復帰します。
ShaderLab理解 コード追っかけてみた

今回の目的
・どのように動作しているか流れを追う
・前回の内容をさらに細かく
　https://qiita.com/moca_uni/items/edd66190168994e58c89

環境
・Unity5.4
・Windows

※Unity ShaderLab Cg/HLSLを想定
自分なりに構造理解（間違っていたら指摘ください）

# 初期準備
①Unityからビルドインシェーダーを取得する
＜Unity公式＞
https://unity3d.com/jp/get-unity/download/archive

②取得したシェーダー内の以下のファイルのみUnityプロジェクトに入れる
　→builtin_shaders-5.4.4f1\DefaultResourcesExtra\UI

③UI-Default.shaderを開く

# 構造体
①struct部
・ユーザーが定義した構造体「appdata_t」に値が入る
・POSITION：ワールド座標、COLOR：色、TEXCOORD0：UV値が自動で入ってくる
　→これ最初わからなかった・・・
　※UV値は画像の大きさに関係なく0～1の範囲、U(横軸)、V（縦軸）で値が入ってくる

②vertex部（v2f vert(appdata_t IN)）
・ここでは取得した情報の加工を行う
　→何もしない場合はそのままフラグメントへ渡す変数「v2f OUT」にそのままの値を渡せばいい
　※少しずらす場合は「OUT.texcoord.x = IN.texcoord.x + 0.1;」を「OUT.texcoord = IN.texcoord;」の後に追記する

③フラグメント部（fixed4 frag(v2f IN) : SV_Target）
・座標を変更した情報を元に着色するところ、今回は以下のコードを記述
　→ return tex2D(_MainTex, IN.texcoord);
　　→vertex部で加工したOUT.texcoordのピクセルを取得して、そのピクセルの色をreturnで確定

# まとめ
・構造体で取得する値を決めて
・vertex部で座標を加工（移動・回転・拡縮）等して形を決めて
・fragment部で色の付け方を決める
・今回の場合「appdata_t→vert(appdata_t IN)→v2f→frag(v2f IN)→return」になっていた
※vertex部/fragment部の細かい内容は後でやる

# 最後に
・Shader本冬コミとかに出したい

お世話になった書籍・サイト
＜Unityシェーダープログラミングの教科書 ShaderLab言語解説編＞超オススメ！！
・https://s-games.booth.pm/items/660001
＜サイト＞
・https://qiita.com/sune2/items/fa5d50d9ea9bd48761b2