OmniAICreator/Qiita-1.07M huggingface dataset:
強化学習２３　Colaboratoryで自分用のmoduleを作って使う

Colaboratoryで自分用のmoduleを作って使う方法です。

まず、GoogleDriveにmodule用のフォルダを作ります。
名前は、chokozainerRLにしました。
chokozainerRL内に、空のファイル　\_\_init__.py　を作ります。
VSCodeでファイルを作って、アップロードしました。
次に、以下のようなtest.pyファイルを作ってアップロードします。

```test.py
class Test:
  def sayStr(self, str):
    print(str)
```

```
chokozainer フォルダ内
    __test__.py
    test.py
```

notebookは以下のような感じです。


```python
import google.colab.drive
google.colab.drive.mount('gdrive')
!ln -s gdrive/My\ Drive mydrive
!ln -s gdrive/My\ Drive/chokozainer chokozainer
```

```python

from chokozainerRL import test
a=test.Test()
a.sayStr("Hello Papa")
```

プログラムが大きくなってくると、自分用のmoduleを作ったほうが便利になります。
【SQLAlchemy】Flask+PythonでのDB連携にはSQLAlchemyがめっちゃ便利だった【Flask】

#結論

インストールするもの

```
pip install flask SQLAlchemy flask-sqlalchemy PyMySQL
```

次にPythonコード

```python:dbcreate.py
# coding:utf-8
from flask import Flask, request, abort
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

#データベースの設定
sql_type, username, password, host, dbname = "", "", "", "", ""#ここは各自で埋めてください。
url = sql_type+"://"+username+":"+password+"@"+host+"/"+dbname
app.config["SQLALCHEMY_DATABASE_URI"] = url
db = SQLAlchemy(app)


class user(db.Model):#一般ユーザー用データベース
    __tablename__ = "user"
    user_id = db.Column(db.String(80), primary_key=True)
    username = db.Column(db.String(255))
    usermessage = db.Column(db.String(255))
    step = db.Column(db.Integer)
    status = db.Column(db.String(255))
    retention = db.Column(db.String(255))
    requested_at = db.Column(db.String(255))

    def __init__(self, user_id, step, retention, requested_at):
        self.user_id = user_id
        self.step = step
        self.retention = retention
        self.requested_at = requested_at

    def __repr__(self):
        return '<user %r>' % self.user_id
```

ここから、ターミナルで作業します。

```
python
>>from dbcreate import db
>>db.create_all()
>>exit()
```

操作：一斉にコミット

```python
reg = user(user_id, None, None, None, 0, "start", None, None)
db.session.add(reg)
db.session.commit()
```

操作：プライマリーキーを使って一部のみ編集

```python
user = db.session.query(user).filter_by(user_id=user_id).first()
user.step = 100
user.status = "ok"
db.session.add(user)
db.session.commit()
```

こんな感じ
AWSからS3にデータをダウンロードするときの個人的メモ（その他ファイル操作に関しても）

##S3からローカルにデータを引っ張ってくる
###1.準備
AWS CLIをインストール。
[参考- AWS CLI 公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-windows.html)

インストール後、`aws configure`を打ち、設定を行う。

```
aws configure
AWS Access Key ID [None]:        AMIアクセスキーを入力
AWS Secret Access Key [None]:    AMIシークレットキーを入力
Default region name [None]:      S3バケットの利用しているリージョンを記入（ap-northeast-1など）
Default output format [None]:    利用するフォーマットを入力（適当でいい？text jsonなど）
```

[参考 - AWS CLI 公式ドキュメント](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-configure.html)

###2. 作業
AWS S3バケットからデータをダウンロードする。
`aws s3 cp s3://バケット名/... /ローカルで保存したい場所`

```
`aws s3 cp s3://bucket-name/log/access.log /local/directory/access.log
```

ダウンロードが開始され、保存が完了する。

##トラブルなど
###EC2からS3（S3からEC2）へ上記を行う際、"An error occurred (AccessDenied) when calling the GetObject operation: Access Denied"と表示され、ダウンロードできない。
EC2に割り当てられているIAMロールのポリシー設定にて、ファイルの操作（GetObject, PutObjectなど）が許可されていない可能性が高いです。

手順：
AWSマネジメントコンソールからEC2に入り、該当するEC2インスタンスを選択。
画面下に表示されている「説明」タブの中に「IAM ロール」に割り当てられているロール名をクリック。
「アクセス権限」タブ→「Permissions policies 」→ポリシー名（前ページのロール名｝をクリックし、「サービス」の中から「S3」をクリック。
[こちら](https://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/list_amazons3.html)を参考に、実行したいアクションを許可する。



##最後に
今回の作業に関して、こちらの記事を参考にさせていただきました。
[Amazon S3にGUI･CLIでファイルをアップロード・ダウンロードする方法](https://dev.classmethod.jp/cloud/aws/amazon-s3-file-up-down/)
PHPで簡易的なフレームワークを作ってみた

#簡易的なPHPフレームワークを作ってみた

簡易的なフレームワークを実際手を動かして作ることで多少なりとも、
現在使っているフレームワーク(Laravel・自社フレームワーク)の理解の助けになればよいと思い作ってみました。


##リクエストの処理をindex.phpに集中させる
.htaccessですべてのリクエストに対してindex.phpが実行されるようにします。
https://sample.jp.localhost/blog/hogehoge
たとえば、上記のようなアクセスがあったら、以下のようなURLにリダイレクトされます。
https://sample.jp.localhost/index.php?url=blog/hogehoge

```text:.htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php?url=$1 [QSA,L]
</IfModule>
```

index.phpはリクエスト時最初に実行されるPHPプログラムです。
```.htaccess```でリダイレクトされることによってどのリクエストもまずはこのプログラムを通ります。

```php:/index.php
require __DIR__ . '/action.php';

$app = new action();
$app->run();
```


index.phpで読み込ませている```action.php```です。
ここでリクエストを判別して```models```以下にあるclassを呼び出しています。

```php:/action.php
<?php
class action {
    public function run() {
        $GET = filter_input(INPUT_GET, 'url');
        $params    = explode('/', $GET);
        $fileName  = array_shift($params);
        $filePath  = './models/' . $fileName . '.php';
        $className = $fileName . '_action';

        if ($fileName && file_exists($filePath)) {
            require './models/' . $fileName . '.php';
            $app = new $className();
            extract($app->handle($params)); //viewに変数をアサイン
            require './views/' . $fileName . '.php';
        } else if(!$fileName || !file_exists($filePath)){
            require './models/index.php';
            $app = new index_action();
            extract($app->handle($params)); //viewに変数をアサイン
            require './views/index.php';
        }
    }
}
```

###models
modelsはGETパラメータが無い時や存在しないURLにリクエストがあったときは```index.php```が読み込まれ、GETパラメータに対応するclassが存在する場合はそれが読み込まれます。
例：https://sample.jp.localhost/blog/
上記のようなリクエストがあった時は```blog_actionClass```が読み込まれる。

```php:/models/blog.php
class blog_action{
  function handle($params){
      return array(
        'title'=>'Hello World! (blog)',
        'h1'=>'Hello World! (blog)'
      );
  }
}
```



```php:/models/index.php
class index_action {
  function handle($params) {
      return array(
        'title'=>'Hello World! (index)',
        'h1'=>'Hello World! (index)'
      );
  }
}
```

###views
viewsは```models```の方で設定した配列のキーが変数として使用できます。

```php:/views/blog.php
<html>
<head>
<meta charset="utf-8">
<title><?php echo $title; ?></title>
</head>
<body>
<h1><?php echo $h1; ?></h1>
</body>
</html>
```

#まとめ
 **「PHP フレームワーク　自作」**とかで検索して色んなサイト参考にさせて頂きました。
フレームワークが実際どういう原理で動いているのかいまいち理解できていなかったのですが、
手を動かすことによって多少は理解の助けになった気がします。

普段の業務ではLaravelや自社製のフレームワークなんかを触る機会が多いですが、
フレームワーク機能を極限まで削るとこんな感じなのかなぁと思います。

##課題
classを読み込む時は**require**でなくて、**autoloader**を使いたかったけどなぜか認識されず要調査。


##GitHub
https://github.com/ysk/php_framework2
Ant Design Vue の Message で複数行表示させる



# AntDesign の MessageAPI

https://www.antdv.com/components/message/

<img width="749" alt="スクリーンショット 2019-11-29 12.26.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36542/fc5fad55-bdfb-6546-362f-ff1a67d2f7b5.png">

AntDesignを使っていれば `this.$message.info('Hello')` などで利用が可能となっています。

<img width="343" alt="スクリーンショット 2019-11-29 12.31.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36542/0be973d7-d467-8fd1-ada8-0402951bdf29.png">

素晴らしいですね。

# 複数行表示したい

[ヒーリングっど♥プリキュア](http://www.toei-anim.co.jp/tv/healingood_precure/)は2020年春からの放映なのでそれも伝える必要があります。
なので2行表示にしたかったためとりあえず改行コードを入れてみます。

<img width="430" alt="スクリーンショット 2019-11-29 12.37.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36542/41a51c4d-2bca-c51e-18b7-3708f4a238ba.png">
おもてたんとちがう…

もちろん `<br>` を入れてもそのまま表示されてしまいます。
このままでは来年春から始まる新しいプリキュアの素晴らしさがうまく伝わりません。

## Stringでは無理

MessageAPIの `info` 関数は第一引数に `string | VNode | (h) => VNode` を取ります。
ということで `string` では無理そうなので他のものを試します。

## VNodeって？

[こちら](https://jp.vuejs.org/v2/guide/render-function.html) で解説してくれていますが仮想ノードにあたります。
要するにこのあたりには直接仮想ノードを渡せますよーということみたいです。

## VNodeの作り方

[ドキュメント](https://jp.vuejs.org/v2/guide/render-function.html) にもあるとおり `createElement` 関数で作成するのが一般的なようです。
しかし `render` 内ではないので該当の関数がありませんが `h` がそれにあたるようです。

> createElement を h にエイリアスしていることは、 Vue のエコシステムの中でよく見かける慣習です。そして、それは実は JSX には必須です。Vue の Babel プラグインの バージョン 3.4.0 以降では、ES2015 のシンタックスで宣言された JSX を含むメソッドや getter（関数やアロー関数は対象外）に対しては、自動的に const h = this.$createElement が注入されるため、(h) パラメーターは省略できます。それ以前のバージョンでは、もし h がそのスコープ内で利用可能でない場合、アプリケーションはエラーを throw するでしょう。

ということだそうです。
ん？ `this.$createElement` でもええんか…？

## ということで

```javascript
this.$message.info(h => {
  return h('span', [
    h('span', 'ヒーリングっど♥プリキュア'),
    h('br'),
    h('span', '2020年春からスタート！')
  ])
})
```

<img width="345" alt="スクリーンショット 2019-11-29 13.01.16.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/36542/402a7420-52ef-8af7-fe09-0c4658e882c0.png">

ヒャッホウ！！
改行だけでなくハートマークを赤くもできますね。

[動作確認したやつ置いときますね。](https://codesandbox.io/s/vue-antd-template-tct50?fontsize=14&hidenavigation=1&theme=dark)

## 面倒くさくない？

[JSX](https://github.com/vuejs/jsx) でもできるみたいです、使えるなら絶対そっちのがいい。
公式もそう言ってます。

次は @karur4n が何かしら書いてくれると思います。
面白い人なので記事もきっと面白いんだろうなあと思います。
ぜひよろしくお願いします。
Python -辞書包括表記を元の形に戻してみた-

現在、内包表記の一つの辞書包括表記を勉強中です。
その途中で、辞書包括表記を元の長めのコードに戻してみたら成功したので、記事に残しておこうと思いました。

##内包表記とは
そもそも内包表記とは、一つ以上のイテレータからPythonデータ構造をコンパクトに作れるものです。（引用：Bill Lubanovic著　斎藤 康毅 監訳　長尾 高弘 訳 　『入門Python3』　P.104
出版社：オライリー・ジャパン　ISBN 978-4-87311-738-6)

辞書包括表記は内包表記の一つで、キーとバリューを用いた辞書の形式で内包表記をしていくものです。

##辞書包括表記を書いてみる

まずは、辞書包括表記を書いていきます。
文字列「python」の一文字ずつをキーとして、それぞれの文字のインデックスをバリューとします。

```Python:辞書包括表記
word = "python"
letter_index = {letter:word.index(letter) for letter in word}
print(letter_count)

>> {"p": 0, "y": 1, "t": 2, "h": 3, "o": 4, "n": 5}
```

このように辞書包括表記をはじめとした内包表記を利用すれば、forループを回して「python」の文字列の辞書を、一行で記述することができます。
まだ慣れるまで時間がかかると思いますけど、きっとめちゃくちゃ楽にコードを書いていけることでしょう！（多分）

##辞書包括表記を元の形に戻してみる

では、Pythonの練習がてら辞書包括表記を元の形に戻していきます。

```Python:元の形へー、戻れ
word = "python"
letter_index = {}
for letter in word:
    letter_index[letter] = word.index(letter)

print(letter_count)

>> {"p": 0, "y": 1, "t": 2, "h": 3, "o": 4, "n": 5}
```

やはり、空辞書を作ってちゃんとforループを使ってletter_countを辞書を作ると、コードが長くなりました。辞書包括表記が、有用であることがよく分かります。

でも、元の形に戻したらPythonの練習になったし、新しい練習方法を見つけられたので良かったです。

###引用
Bill Lubanovic著　斎藤 康毅 監訳　長尾 高弘 訳 　『入門Python3』
出版社：オライリー・ジャパン　ISBN 978-4-87311-738-6
応用カリキュラム 09

##renderメソッドをコントローラーで使う

[renderを分かりやすくまとめてくれてる](https://qiita.com/hayashino/items/c2a4e7d3edbdcce3cd2a)

ビューで使う場合と、コントローラで使う場合で動きが違うっぽい。
ビューで使う場合は(主に？)部分テンプレートとして使う。

```erb
 <%# _tweet.html.erbファイルをテンプレートとして使う場合 %>
<%= render partial: ‘tweet’ %>
```

となるが、
コントローラの場合は、特定のアクションのビューを呼び出す。

```erb
render action: :new <%# 同じコントローラ内のnewアクションのビューを呼び出す %>
render template: "review/new" <%# 違うコントローラ内のnewアクションのビューを呼び出す %>
```

redirect_toと比較して、HTTPリクエストを送らない、のが特徴らしい。


#### モデルインスタンス.users << current_user で特定のグループのユーザー集合にログインユーザーを追加
#### モデルインスタンス.save データ保存が成功したか否かを返すメソッド
#### 「if (last_message = messages.last).present?」と記述することで、最新のメッセージを変数last_messageに代入しつつ、メッセージが保存されているかどうかで場合分けを行なう。
#### if文を省略して1行に書く書き方を三項演算子と呼ぶ
　条件式 ? trueの時の処理 : falseの時の処理
#### railsにおけるDBの値の表示

まず、DBの値にアクセスするには、コントローラかモデルでインスタンス変数を定義しておく必要がある、と自分は思い込んでいた。

ユーザー管理が必要なサービスでdeviseを適用しているならば、コントローラでのインスタンス変数定義より先にdeviseに関係するインスタンス変数とかローカル変数が定義されており、そのdeviseの変数を介してテーブル(モデル定義時にdeviseオプションをつけたテーブル)にアクセスすることが可能。
更にテーブル(モデル)同士のアソシエーションを繋いで定義しているならば、コントローラでインスタンス変数を定義せずとも、deviseの変数を介してテーブルを参照することができる。current_user.group.messageみたいな表示ができる。

current_user.groups
current_user : device経由でuserモデルを定義した時に、userテーブルと紐づいたインスタンスがcurrent_userをはじめその他の変数に定義されてる
.groups : usersテーブルからアソシエーション定義によって紐づいたgroupsテーブルの情報を取得することができる。

####覚えたいことは、ビューで変数を参照したい場合でも必ずしもコントローラでインスタンス変数の定義をする必要はない、ということ。

#### HTTPリクエストからのルーティング⇨コントローラ⇨ビューについて

アクションに対応するレスポンスとして、ビューを表示するのみ、であったなら
コントローラにアクションメソッドを定義する必要がない。（ちゃんとビューファイルを用意しておけば)ルーティング⇨(コントローラ飛ばして)ビュー、となる。

#### indexアクションへオプション(通知用メッセージ)付きでリダイレクト
redirect_to ({:action => 'index'}), :notice => 'message'
Gitでローカルに残った不要なディレクトリを削除

Gitでリソースを管理している際に、リモートでは消えているはずのディレクトリが、ローカルでは残ったままになっていることがあったので、解決策のメモ。

## git clone
ローカルのリポジトリを削除して、リモートからクローンし直す。これが1番手っ取り早いし、確実にリモートとローカルが一致する。ただ、如何せん脳筋っぽいし、どうせならスタイリッシュにやりたい。

## git clean
追跡していないファイルを作業ディレクトリから削除するコマンド。

- `git clean -n` 追跡していないファイルを確認
- `git clean -f` 追跡していないファイルを削除
- `git clean -f PATH` パスを指定して追跡していないファイルを削除
- `git clean -df` 追跡していないディレクトリも含めて削除

今回のケースだと`git clean -dn`で削除されるディレクトリを確認、問題なければ`git clean -df`で削除といった流れ。
selectタグで複数選択に変えたら、ストロングマラメーターによってパラメーターが排除されてしまった

webサイトを作成中にselect_tagを複数選択に変えたら、 入力した値が排除されてしまい少しハマってしまったので同じミスをしないためにまとめます。

#エラーが発生した状況
<img width="921" alt="スクリーンショット 2019-11-29 0.19.10.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/12cd06c3-e607-b311-69f7-4c38526abf2e.png">
上の写真のようにselect_tagを複数選択に変えたところ、これまで正常に登録ができていたにもかかわらず、登録できないエラーが発生した。
ログをみてみると、「Unpermitted parameter: :category_id」となっており、ストロングパラメータで弾かれ、paramsの値がnilになっていることが原因のようだった。
<img width="281" alt="スクリーンショット 2019-11-29 0.20.07.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/c938e571-9afd-b136-adb9-ea59cdcc6dd0.png">
コンソールでも確認してみたところnilになっている
<img width="582" alt="スクリーンショット 2019-11-29 0.21.00.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/d68c26de-a53e-5e3d-7838-829f099a131e.png">


#解決のために試したこと
ストロングパラメータを書いたコードをみて、paramsで指定した値の入力ミスがあるか確認。
しかし、タイポしているわけではなさそう。複数選択を解除すれば問題なく通ったため、複数選択が原因であることは間違えなさそう。
<img width="576" alt="スクリーンショット 2019-11-29 0.18.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/f2d7bfef-49d1-19f8-f6d7-ba1af078a16e.png">

複数選択の時と一つしか選択できない時のparamsに入っている値を確認してみる。
・一つ選択の時
<img width="601" alt="スクリーンショット 2019-11-29 0.20.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/98549262-75df-b4bf-d9ce-bbdc41386079.png">
・複数選択の時（pryを使用してparamsの値を確認）
<img width="634" alt="スクリーンショット 2019-11-29 0.20.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/ff40d95c-b5ee-28a2-2c0e-fcf51d8a90ec.png">

確認してみると、複数選択の場合、値が配列になっていることからストロングパラメーターにもそれを追記しなければいけないのではと思い実行したら、うまく作動できた！
<img width="546" alt="スクリーンショット 2019-11-29 12.54.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/444064/cba75821-01f5-561b-e08f-286c7bd98bef.png">


```
params.require(:posting_thread_categories).permit(:category_id)
# 上記から以下に変更
params.require(:posting_thread_categories).permit(category_id: [])
```
【PHP】PHPのデバッグで滅茶苦茶よく使う関数、”var_dump()”を紹介する記事

皆さんは、PHP開発をするうえで「あの関数、中身どうなってるんだ？」と疑問を呈した事は無いでしょうか？
いちいち中身を確認する為に、実行して結果が思ったものと違って、かといって原因はわからない…
そんな経験もあるものかと思います。

そんな状態を解決してくれるのが、この[var_dump]です。これは、いわゆるデバッグに使う関数で、使うとその便利さに驚くはずです。
ここでは便利な**var_dump関数について、使い方&仕様を解説します！**

#var_dump()の動きを解説


まず下記のテストコードを打ち込みます。

```php:var_dump_testCord.php
<?php
$a = 1;
$b = "test";
$c = "";
$d = 1.234567890;
$e = ["apple" => 3,"banana" => "sweet","orange" => 7];

var_dump($a);
var_dump($b);
var_dump($c);
var_dump($d);
var_dump($e);

```

すると出力は以下の通りになります。

```php
//$a
int(1)

//$b
string(4) "test"

//$c
string(0) ""

//$d
float(1.23456789)

//$e
array(3) {
  ["apple"]=>
  int(3)
  ["banana"]=>
  string(5) "sweet"
  ["orange"]=>
  int(7)
}
```

どうでしょう？
var_dump関数を用いる事で、変数の中身がただ出力されるのみならず、なんと内部でのプリミティブ型（０か１の型を示すbool値とか、文字列のstring値のような「変数の種類」を示すもの）付きで、さらに変数の中身が表示されるようになります。

int型/float型の場合は、（）の中に変数の中身が入ります。
string型の場合、（）の中身は"半角/全角スペースを含めた文字列の文字数"が表示され、更にその後に変数の中身が表示されます。
array型の場合、（）の中身は何とarrayの中身の数と、中のプリミティブ型とその具体的な仕様まで詳しく出てきます。

#おまけ：デバッグ向け関数には、print_r()という関数もある。

var_dump関数はデバッグで有用という事をお伝えしましたが、実は似たような用途の関数に。"print_r"関数というものもあります。
こちらは、いうなればvar_dump関数の簡易版ともいえる仕様です。

プリミティブ型は表示させず、そのまま関数の中身を表示してくれるという仕様です。

試しに、上記のテストコードで書いたvar_dump()の部分を、全てprint_r()に書き換えてみましょう。
出力は以下の通りです。

```php:print_r
123test1.23456789Array
(
    [apple] => 3
    [banana] => sweet
    [orange] => 7
)

```

簡易的ですね。情報量が少なくなっており、更にソースコード自体に工夫をせねば改行もありません。
var_dumpするまでも無いと思えるデバッグをするのなら、使ってみてもいいかもしれません。
opencvによるリアルタイムでの画像処理基礎

#はじめに
パソコンについているカメラで、リアルタイムでその画面を表示させるプログラムの紹介

#環境
言語：python3
ライブラリ：opencv
エディタ：jupyter notebook

#ソースコード
```python
import cv2

#captureの準備
cap = cv2.VideoCapture(0)

#起動と画面表示まで
while(1):
    #capture frameの作成
    _, frame = cap.read()
    cv2.imshow('Original', frame)
    
    #originalの反転（鏡状態）
    original = cv2.flip(frame, 1)
    cv2.imshow('Inversion', original)
    
    #binarization
    gray = cv2.cvtColor(original, cv2.COLOR_RGB2GRAY)
    cv2.imshow('Binarization', gray)
    
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

cv2.destroyAllWindows()
cap.release()
```
"Original"はカメラによってとらえられた本体である。
"Inversion"はoriginalの画面の反転を行うことにより、鏡のように見せている。
"Binarization"はInversionの画面を二値化(=binarization)をしたものであり、白黒になる。

今回は処理がわかりやすいが、コードを書く人によっては以下のように並べ替えられる。

```python
import cv2

#captureの準備
cap = cv2.VideoCapture(0)

#起動と画面表示まで
while(1):
    #capture frameの作成
    _, frame = cap.read()

    #originalの反転（鏡状態）
    original = cv2.flip(frame, 1)

    #binarization
    gray = cv2.cvtColor(original, cv2.COLOR_RGB2GRAY)

    
    k = cv2.waitKey(5) & 0xFF
    if k == 27:
        break

    cv2.imshow('Original', frame)
    cv2.imshow('Inversion', original)
    cv2.imshow('Binarization', gray)

cv2.destroyAllWindows()
cap.release()
```
何も処理自体は変わらない。しかし、処理の塊としてみるには下記の方がプログラマーとしては見やすいかもしれない。いちいち一個ずつ処理してるように見えてしまうからである。

#さいごに
今回は基礎中の基礎をやった。これを応用したものもこれから書いていくし、ほかのライブラリを含めて様々なことができるので、やってみるといい。
HtmlFormでDeleteやPutを表現する


HTMLの標準では、FormはGETとPOSTしかサポートしていない。
擬似的にフォームでDeleteとPUTを表現したい場合は、パラメーターにmethod情報を含める。

Railsのフレームワークは内部の処理で隠されたDeleteフォームを生成することでDeleteFormを表現している。

```html:template.html
<form method="POST">
  <input type="hidden" value="delete" name="_method">
</form>
```
NativeとWeb側の接続

Native側で、JavaScript機能の呼び出し、 

```
func getImages() {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
            appWebView?.evaluateJavaScript(
            "getLastImages()") { (result, error) -> Void in
                if error != nil {
                    print(error as Any)
                }
                print(result as Any)
            }
        }
    }
```

JavaScriptからJsonポストして、

```
getLastImages: function() {
      let message = {
        cmd: 'lastimages',
        count: '1',
        callbackFunc: function(responseAsJSON) {
          let response = JSON.parse(responseAsJSON)
          let image = response['image']
          if(image){
            self.form.image_white = image
          }
        }.toString()
      }
      window.webkit.messageHandlers.native.postMessage(message)
    }
```
Native側のHandlerは、

```
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    let sentData = message.body as! NSDictionary
    let command = sentData["cmd"] as! String
    var response = Dictionary<String,AnyObject>()
    if command == "lastimages"{
                appWebView?.evaluateJavaScript(
                "document.getElementById('fetchimage').style.display = 'none';") { (result, error) -> Void in
                    if error != nil {
                        print(error as Any)
                    }
                    print(result as Any)
                }
                concurrentQueue.sync {
                    var imageString = [String]()
                    imageString = imgProcessHandler.identifyFetchResult()
                    response["image"] = imageString as AnyObject
                    let callbackString = sentData["callbackFunc"] as? String
                    self.sendResponse(aResponse: response, callback: callbackString)
                }
        }
｝
```
PWA+Angular8＋AWS amplifyを試す PART#1

# きっかけ
最近話題のPWAを試してみようと思い、メモを兼ねてQiitaへの投稿を始めてみた。
本業は組込みシステムのソフトウェアに携わっており、WEB系は初心者です。
初心者ながら少しずつ成長する姿を見守っていただければ幸いです。
アドバイス等頂けると助かります。

# PART1
・Angularの雛形を作る
・angular/cliをインストール
・ブラウザに表示されるかテスト


# 環境
```
     _                      _                 ____ _     ___
    / \   _ __   __ _ _   _| | __ _ _ __     / ___| |   |_ _|
   / △ \ | '_ \ / _` | | | | |/ _` | '__|   | |   | |    | |
  / ___ \| | | | (_| | |_| | | (_| | |      | |___| |___ | |
 /_/   \_\_| |_|\__, |\__,_|_|\__,_|_|       \____|_____|___|
                |___/
    

Angular CLI: 8.3.20
Node: 12.13.1
OS: win32 x64
Angular: 8.2.14
... animations, common, compiler, compiler-cli, core, forms
... language-service, platform-browser, platform-browser-dynamic
... router

Package                           Version
-----------------------------------------------------------
@angular-devkit/architect         0.803.20
@angular-devkit/build-angular     0.803.20
@angular-devkit/build-optimizer   0.803.20
@angular-devkit/build-webpack     0.803.20
@angular-devkit/core              8.3.20
@angular-devkit/schematics        8.3.20
@angular/cli                      8.3.20
@ngtools/webpack                  8.3.20
@schematics/angular               8.3.20
@schematics/update                0.803.20
rxjs                              6.4.0
typescript                        3.5.3
webpack                           4.39.2
```
Visual studio code/1.40.1を使用しています。


# Angularの雛形を作る
``` 
md angular-pwa
cd angular-pwa
```

# angular/cliをインストール
``` 
npm i @angular/ci
```
今回はローカル環境にangular/cliをインストールする。
ローカルインストールの為、-gを付けない

# ng newでangular雛形を作成
```
npx ng new angular-pwa --directory=./ --routing=true --style=scss  
```
プロジェクトフォルダは先に作成しているので、--directoryオプションでインストール先をカレントに指定する。
--routing, styleオプションはお好みで。

# ブラウザに表示されるかテスト
```
npx ng serve
```
[http://localhost:4200/](http://localhost:4200/)にアクセスして以下のような表示になれば成功。

![1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/231550/4f8733d5-01b4-7508-b3a8-d79fd8822417.jpeg)

# 次回
今回は、angularのインストールから動作確認まで行いました。
次回は作成したプロジェクトをgithubにレポジトリを作成して管理します。

[PART2: GitHubリポジトリ登録](https://qiita.com/mitapach/items/f8220bd846abc8b877c2)
すごい！！Unityって鍋の裏もレンダリングできるんだね！！【HDRP: 異方性反射マップ】


この記事は【unityプロ技】 Advent Calendar 2019の12/3の記事です。
[【unityプロ技】 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/unityforpro)

こちらの記事は、以下のページに移植・加筆修正しました。ぜひこちらをご覧ください。
https://3dcg-school.pro/unity-hdrp-anisotropy-map/

#おまけ
サンプルをアセットストアに出品しました。アニソトロピー表現を詰め込んだマテリアル集となっております。手早くアニソトロピーを体験したい方は、こちらをどうぞ。
###[Anisotropy Material Pack](https://assetstore.unity.com/packages/slug/158127?utm_source=jppt&utm_medium20191203)
[<img width = 400 src = "https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/383267/2dd29854-1c82-e88a-df4c-5b51bfa35ece.jpeg">](https://assetstore.unity.com/packages/slug/158127?utm_source=jppt&utm_medium20191203)

また、上のアセットをストアに出品した手順を記事にし、同日別のアドベントカレンダーで公開しました。アセットストア出品に興味のある方はご覧になってください。

- [お蔵入りをお金に換える！！UnityAssetStoreに出店する手順まとめ](https://qiita.com/yarikomivr_com/private/caf968987c939a020db6)

###参考文献
https://learn.foundry.com/modo/901/content/help/pages/shading_lighting/shader_items/anisotropic_direction.html
https://help.sketchfab.com/hc/en-us/articles/360020687812-Anisotropy
お蔵入りをお金に換える！！UnityAssetStoreに出店する手順まとめ

この記事は「Unityアセット冬のアドベントカレンダー 2019 Winter！」の12/3の記事となります。
[Unityアセット冬のアドベントカレンダー 2019 Winter！](http://assetstore.info/asset-advent-calendar-2019-winter/)

この記事は、[こちら](https://3dcg-school.pro/unity-asset-store-how-to-publish/)に移行しました。
〈初心者向け〉ユーザビリティテストを簡単に始めるためにやった、5つのこと

# はじめに
経験のないエンジニアがユーザビリティテストを簡単に始められるように準備すべきことをまとめています。
ターゲットユーザ（ペルソナ）が明確になっていることが前提条件です。

# 流れ
1. 開発メンバに説明
2. テスト対象の選定
3. ユーザシナリオの洗い出し
4. インタビュー内容の洗い出し
5. テスト当日向けの事前準備

## 1. 開発メンバに説明
1人でやるものではないので、チームのみんなに必要だと共感・納得してもらう必要があります。
※1人で実施できないわけではありませんが、お勧めはできません。観察からの気付きが減ったり、共通認識が取れていないことによってメンバ間の開発物に差が生じて手戻りが発生することになります。
　
__説明の流れ__

 - ユーザビリティテストとは？
 - なぜやるのか？
 - 何に使えるのか？
 - どうやってやるのか？

## 2. テスト対象の選定
全てをテストすることは現実的ではありません。実行するハードルを低くするためにも、対象シナリオを1～2つに選定します。使用頻度、タイミング、状況、場所などから優先順位をつけましょう。
（例）導入時にターゲットユーザが取る行動2つ（○○設定、△△設定）

## 3. ユーザシナリオの洗い出し
実際のターゲットユーザは設定した利用状況でどのような行動を取るか想定します。システムのボタン押下、〇〇の入力など細かく書くのがポイントです。この時点で「あれ？このシステムって使いづらい・・・」と改めて気付きます。

## 4. インタビュー内容の洗い出し
実際にタスク実行中の様子を観察しないと分かりませんが、事前に全員で考えつく限りの内容を洗い出すことをお勧めします。なぜかというと、タスク実行後のインタビューは基本的に1人で行うものです。初心者のインタビュアーが「1人でインタビューしてユーザの行動理由、感情、心理などを引き出さなければならない」というプレッシャーに耐えられるでしょうか。事前に全員で考えておくことによって、リラックスしてインタビューできます。また、観点抜け漏れの防止に役立ちます。

## 5. テスト当日向けの事前準備
はっきり言ってここが一番大変です、やることが多いです。やらなくてもいいこともありますが、先を見据えてテストするのであれば数値で比較できる「評価指標の選定」はやっておいた方がいいと思います。

__必須__

 - プレテスト用の被験者と日程調整（最低でも2時間くらいを想定）
 - テスト用の被験者と日程調整（3～5名に実施、予想以上に時間がかかります）
 - タスク指示書の作成（ターゲットユーザになるべく分かりやすい言葉にしましょう）
 - 当日用説明資料作成
 - プレテストの実施

__任意__

 - 営業に日程調整（営業からの説明を受けた後にターゲットユーザがタスク実行する場合）
 - 評価指標（定量調査）の選定（SUS、NPSなど）
 - 開発メンバがタスク実行したときの時間の計測
ROOTでデータファイルをTgraphErrorsでPlot(Fitなどのおまけつき)

TGraphErrorsを用いてデータが書かれているテキストファイルから簡単にROOTを用いてプロット、Fitなどを行います。~~脱Excel,gnuplot~~

# 前提

以下のようなデータファイル(data.dat)があるとします。

```data.dat
1 1 0.1 1 0.2
2 2 0.2 4 0.4
3 3 0.3 9 0.9
...
```

全部で5列あって、x y1 dy1 y2 dy2となっているとします。

# 実装

ROOTを開いて次のようにファイルを読み込みます。

```
root [] TGraphErrors* tg1 = new TGraphErrors("data.dat","%lg %lg %lg %*lg %*lg"); // (x,y1,dy1)の組のGraphを作る
root [] TGraphErrors* tg2 = new TGraphErrors("data.dat","%lg %*lg %*lg %lg %lg"); // (x,y2,dy2)の組のGraphを作る
root [] tg1->Draw("ap"); // option a = axis, p = point
root [] tg2->Draw("p"); // 2つめ以降はaxisはDrawしない
```

[TGraphErrors](https://root.cern.ch/doc/v608/classTGraphErrors.html)ではデータが入った配列<sup><a href="#1">*1</a></sup>やTVectorDなどを突っ込んで動くコンストラクタがありますが、いつも私は~~チャラく~~お手軽にファイルに書き出したデータをプロットするのに使っています<sup><a href="#1">*2</a></sup>。

この場合ではこのコンストラクタ

```
TGraphErrors TGraphErrors(const char* filename, const char* format = "%lg %lg %lg %lg", Option_t* option = "")
```

を使っています。データフォーマットは

- %lg %lg %lg %lg  (x,y,dx,dy)
- %lg %lg %lg      (x,y,dy)
- %lg %lg          (x,y)

のように自動で認識します。
データファイルの中で無視する列は **%*lg** とすると良いです(これをいつも忘れるから書いた)。

<span id="1" style="font-size:small">*1: 動的配列であるstd::vectorでも出来ます。

```
std::vector<Double_t> x,y,dx,dy;
/*
x,y,dx,dyに詰める
*/
TGraphErrors* tg = new TGraphErrors((Int_t)x.size(),&(x.at(0)),&(y.at(0)),&(dx.at(0)),&(dy.at(0)));
```

</span>

<span id="2" style="font-size:small">*2: このやり方だと、書かれているデータに何らかの処理をしてプロットすることは出来ないのでマクロなどで[以前の記事](https://qiita.com/sho0405/items/fd15d7d21b941286d4b0)のようにデータファイルから配列を取得して処理してからTGraphErrorsのコンストラクタに突っ込む、もしくはawkなどを使って予めデータを処理しておくことが必要になるでしょう。</span>

# おまけ

TGraphErrorsはTGraphを継承しているのでFitなども当然出来ます。これが良いところ。

```
root [] tg1->Fit("pol1");
root [] tg2->Fit("pol2");
```

Fitの関数はよく使うものとしては"polN" (n次多項式), "gaus" (Gaussian)などでしょう。自分で関数をTF1で作ってFitも出来ます。
ここで

```
root [] tg1->Fit("pol1","rob");
```

とすると、ROBUST Fittingというのをやってくれます。
これは、データをある関数でFitするときに外れ値がいるとそいつに強く引っ張られてしまいますが、それをなるべく抑えてFittingしてくれるメソッドなのだそうです([参考](https://root.cern.ch/root/html600/TLinearFitter.html))。

ついでに、グラフタイトル、軸ラベルの変更などしてしまいましょう。

```
root [] tg2->SetTitle("y = x^{2}"); // TLaTeXが使えます
root [] tg2->GetXaxis()->SetTitle("x");
root [] tg2->GetYaxis()->SetTitle("y");
```

`#alpha` などとするとギリシャ文字も書けるし、原子核の核種などもプロット内に記述できるので[TLaTeX](https://root.cern.ch/doc/master/classTLatex.html)は度々重宝しております。
【MS Teams】Incoming Webhook経由で画像を送信する方法

# はじめに

MS TeamsではIncoming Webhookを利用することで
外部から特定チャンネルに対してメッセージを送ることができます。

今回は画像を送ることに焦点を当てた記事を記載します。
なお、添付ではなく参照と埋め込みになります。


# case１　インターネット参照が可能なURLを記載する

公式サイトにも書いてありますが、
ActivityImage等にインターネット参照が可能なURLを書くと画像が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/6790ff63-3680-c86c-a511-1374aec5dce5.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/3fe481f1-7a07-12aa-cd92-947f0f47c0a5.png)


[従来の操作可能なメッセージ カード リファレンス](https://docs.microsoft.com/ja-jp/outlook/actionable-messages/message-card-reference)

heroImageは記載時点ではTeams非対応な気がします。

　

上記のサイトがオーバーワークだなと感じた場合は、
@miyamiya さんの記事が分かりやすいかと思います。

[Microsoft Teams に PowerShell で投稿してみる](https://qiita.com/miyamiya/items/ccae505b8e97b5b532a7)



# case２　画像をメッセージに埋め込む

インターネットから参照可能な場所に画像があるとも限りません。

かくいう自分も外からは参照できない社内サーバにある画像を送信する必要がありました。
（日次、週次レポートの通知が目的）

ではどうするか。

公式サイトにも記載がありますが、Json形式内でMarkDown記法が使えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124594/ed29e79b-da40-959c-537a-d94eaf516b9a.png)

MarkDownでは以下のように記載することで、
base64に変換することで埋め込むことができます。

```markdown:画像埋め込み
![Weekly Report](data:image/png;base64," + {base64に変換した画像を文字列として記載} + ")
```
　

注意点は以下の２点です。

##### Teamsで表示できるサイズに閾値がありそう

偶然14KBと16KBの画像を連続して送信した際に気がついたのですが、
15KBを超えると表示できない気がします。

公式情報を見つけたというわけではないため、別問題かもしれませんが・・・。

リサイズや減色等で圧縮してあげてから送信したほうが無難かなと思います。

##### クリックしても拡大できない

これはしょうがないものでしょうか・・・。
「なんかMacのネットワーク接続悪いなぁ」と思った時にやったこと

#なんかブラウザ見れない。。。
大学のwifiに接続してブラウジングしようと思ったらなんかうまくいかなかったので
どのように解決したのか。

<img width="647" alt="スクリーンショット 2019-11-29 12.22.27.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415059/6f7de49b-84a0-61de-0da4-c8555632d5c1.png">


ここをみるとDNSって書いてあったけど気づけなかった...



##Wiresharkを起動してみる。
最近付け焼き刃で覚え始めてるwiresharkを開いてみた。

そうすると...

<img width="93" alt="スクリーンショット 2019-11-29 12.24.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/415059/186e3c48-c0e7-300d-c052-cf54dab57fcf.png">


DNSがめちゃめちゃがんばってる


よって大学のホームページから指定されてるdnsサーバーのipアドレスを発見。
macのdnsを変更して無事解決！
C#で固定値とリストを含むjsonをデータベースに登録する

##固定値とリストを含むjsonをデータベースに直接登録したい。

何言ってんの？って感じですよね、ごめんなさい。
ちょっと日本語で説明すると伝わりづらいですが、要はこんなようなjsonを直接データベースに登録したい。

```json:SKILLTABLE.json
{"NAME": "Akira",
 "SKILL": [
    {
	    "LANGUAGE": "C++",
	    "EX_YEAR": "4"
    },
    {
	    "LANGUAGE": "Java",
	    "EX_YEAR": "3"
    },
    {
	    "LANGUAGE": "C#",
	    "EX_YEAR": "2"
    }
  ]
}
```

登録後のイメージはこんな感じ。
一つの値は固定で、他のリスト部分は順々に登録したい。

| NAME        |   LANGUAGE     |    EX_YEAR   |
|:------------|---------------:|:--------------------:|
| Akira       |   C++          | 4                    |
| Akira       |   Java         | 3                    |
| Akira       |   C#           | 2                    |

##やってみた
###まずはプログラム上でJSONファイルを作成する。

（職場で書いたコードを思い出しながら編集しつつ書いてるので、細かいミスなどあるかもしれませんすいません）

```csharp:engineer.cs

//クラス定義
[JsonObject("skill")]
class Skill{
    [JsonProperty("language")]
    public string language {get; set;}
    [JsonProperty("ex_year")]
    public int exyear {get; set;}

    public Skill(string lang,int year){
        this.language = lang;
        this.exyear = year;
    }
}
[JsonObject("engineer")]
class Engineer{
    [JsonProperty("name")]
    public string name {get; set;}
    [JsonProperty("skilllist")]
    public List<Skill> skill {get; set;}

    public Engineer(string Name,List<Skill> skilllist){
        this.name = Name;
        this.skill = skilllist;
    }
}

//JSONファイルを作る
List<Skill> skillList= new List<Skill>();
Skill cplus = new Skill("C++",4)
Skill java = new Skill("Java",3)
Skill csharp = new Skill("C#",2)
skillList.Add(cplus);
skillList.Add(java);
skillList.Add(csharp);

Engineer engineer = new Engineer("Akira",skillList);
string json = Newtonsoft.Json.JsonConvert.SerializeObject(engineer);
```

なんで最初から"Name"のメンバ変数加えとかないの？って思われるかもしれないですが
「Skillのリストが引数として与えられて、そこに名前だけ後付したい」
という要求があるものとしてみてください。

###jsonをデータベースに登録する
```csharp:engineer.cs

String sql;
sql = $"DECLARE @json NVARCHAR(MAX) = '{json}';" +
        $"DECLARE @name = 'SELECT name FROM OPENJSON(@json)WITH(name varchar(10) '$.name');'" +
        $"INSERT INTO table SELECT @name, language, ex_year FROM OPENJSON(@json,'$.engineer')" +
        $"WITH(language varchar(10) '$.language', ex_year varchar(2) '$.ex_year)"

```
データベースに接続する部分だったり、SQL実行する部分は書いてないですが
それは他の記事やブログにも色々書いてあるので割愛します。
このSQLを叩いてあげれば登録できるはずです。

##おわり
SQLど素人だったのでこの方法を見つけるまでに大変時間がかかりました...
同じように困ってる人のヒントになれば幸いです。
冗長な書き方してる可能性があるので、その場合はご指摘お願いします。
AWS認定資格取得 虎の巻

##最短突破 AWS認定ソリューションアーキテクト アソシエイト 合格教本
[出版記念イベント](https://connpass.com/event/125435/)に参加した時の情報を備忘録としてまとめておきます。
なお、自分自身がAWSについて勉強して試験合格した時のメモは[こちら](https://www.slideshare.net/ShinjiIto3/aws-164442925)にまとめてあります。

- 2018年2月に改定されてからそのまま
 - AWSの仕様は頻繁にアップグレードされるので、仕様と出題内容との間にギャップがあるかもと捉えました。そのためいつ試験が改定されたのか把握しておく必要もあると思いました。しかし、実際に受験してみて重箱の角を突く様な出題は少ないと感じました。

- 手を動かさないと受からないタイプの試験
 - 合格だけが目的ではないので、公開されているセルフスペースラボや１０分間チュートリアル、アカウント作成して手を動かしました。

- ベストプラクティスが分からないと回答に迷う
 - 言い換えると最先端企業と同様のシステム設計を使うことができ、他の仕事が出来ることを意味すると捉えています。

- 最初から読むと時間なくなる、何を聞いてるのか想定しつつ読んで把握する
 - Well-Architectedの5本の柱の中からどれかが当てはまる。なお、カッコ内は覚え方です。SCPは「scpコマンド」のscpと覚えました。
  - セキュリティ（S）
  - コスト最適化(C)
  - パフォーマンス効率(P)
  - 信頼性(信頼)
  - オペレーショナルエクセレンス（運用）

- 回答は消去法が使える
 - 明らかに違うよという回答が結構ありますので、ちゃんと勉強すれば２択まで絞れます。

- 最初はソリューションアーキテクトアソシエイトが良い
 - 私はインフラが生業なものでソリューションアーキテクトが合っていたと思います。好きな試験を自由に受ければ良いと思います。

- 日本語訳が怪しいときは英語に切り替えられる
 - 確かに怪しい出題がありますので、1〜２問ほど切り替えました。

- 上位試験のソリューションアーキテクトプロフェッショナルはAWSサービスの知識だけではダメ。オンプレミスやユースケースの経験が必要（リインベントのユースケース）
 - 試験時間が足りない
 - 結構落ちる人いるそうです

- ブログやってたら本の仕事がきた

- 可用性(availability)と耐久性（durability）の違い
 - S3の可用性は4ナイン（99.99%）、耐久性は11ナイン（99.999999999%）

- フェデレーション 

次は、SysOpsアドミニストレータ取得に向け、勉強していきたいと思います。
unity webGL build ハマッた　メモ

カメラの設定は512x521とか２の乗数がいい

```c#:cam.cs
webCam = new WebCamTexture(devices[0].name, 512/*(int)rawImage.rectTransform.sizeDelta.x*/, 512/*(int)rawImage.rectTransform.sizeDelta.y*/, 15);
```

エディターではうごくけど
webでは黒くなった


playersettingはwebassenble streamingのチェックは外したほうがいい。
これあるとロードが最後までいかないときがある

C#上のwebsocketの変換がうまくいかない←いまここnow

WebSocket4Net
apacheでvirtualhostを構築した時のハマりどころ

https://pointsandlines.jp/mac/apache-virtual-host

こちらの記事を参考にさせてもらったのですが、ハマったので、備忘録として。

構築手順はそのままなんだけど、httpd.confファイルの

＃LoadModule userdir_module libexec/apache2/mod_userdir.so
↓
LoadModule userdir_module libexec/apache2/mod_userdir.so

コメントアウトを外さないと、ユーザーディレクトリへのパスが有効にならないようです。
Alacrittyを0.3.0から0.4.0にアップデートしたきのWarn対応

## 前回
[Alacrittyを0\.3\.0から0\.3\.3にアップデートしたきのWarn対応 \- Qiita](https://qiita.com/ume3_/items/1fcd98f056ddcaa58fa7)
こちらの続き。

## 今回
Alacrittyをアップデートしてみたところ以下の警告が出た。
`$XDG_CONFIG_HOME/alacritty/alacritty.yml` の変更が必要と判断。
修正箇所を記載する。

なお、環境はMacOSX。バージョンは0.3.3 -> 0.4.0とする。
[Releases · jwilm/alacritty](https://github.com/jwilm/alacritty/releases)

`brew cask upgrade alacritty` の後に起動するとまず以下の警告

### [WARN] Config scrolling.faux_multiplier is deprecated
> [WARN] Config scrolling.faux_multiplier is deprecated; the alternate scroll escape can now be used to disable it and `scrolling.multiplier` controls the number of scrolled lines

Release情報より`Removed`
> Deprecated scrolling.faux_multiplier, the alternate scroll escape can now be used to disable it
and scrolling.multiplier controls the number of scrolled lines


該当コミットも確認。
https://github.com/jwilm/alacritty/pull/2855
単純に他の機能導入により不要となったので削除でよいと判断。

```diff

scrolling:
-  faux_multiplier: 3
```

これで今回は修正OK。警告は消えた。
1.0になるまでは見守っていきたい。
[UE4]Cinematic Viewportでグリッドやレーターボックスを表示する

![2019-11-29_12h02_53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/20c2953d-67b4-1612-9248-41bfe6cabf2c.png)
右上のアイコンを押すとメニューが出てきます。
![2019-11-29_12h04_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/4ce9adaf-8cd4-87b1-49ea-24f927e90b9c.png)
3分割
![2019-11-29_12h04_54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/05a156b7-f725-5bb9-d07e-132ab14cc246.png)
2分割
![2019-11-29_12h05_10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/0e748fe3-9f19-9d13-b1a4-7846d952eba3.png)
レターボックス
![2019-11-29_12h06_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/4e56e209-1d56-267f-46dc-6311f75b82ba.png)
git で checkout せずに他のブランチのファイルを見たい

git で、あるブランチ x で作業しているときに、他のブランチ y で追加されたファイル hoge.rb の内容を知りたくなった。そういうときにどうするか。
git show にブランチ名を与えると見ることができるらしい。リダイレクトすれば取り出す事もできる。

```
git show y:hoge.rb 
git show y:hoge.rb > file 
```

https://stackoverflow.com/questions/7856416/view-a-file-in-a-different-git-branch-without-changing-branches

bat 使えばもっと見やすくできる

```sh
git show y:hoge.rb | bat -l ruby
```

Emacs では `M-x magit-find-file` の後にブランチ名、そしてパス付きのファイル名を与えれば同じことができる。
Refs モードなら、カーソルがあたっているところがデフォルトのブランチ名になる。

https://emacs.stackexchange.com/questions/7655/how-can-i-open-a-specific-revision-of-a-file-with-magit
rails-tutorial第1章

#コマンド
###ls
今いるディレクトリにどんなファイルがあるか教えてくれる。

###git --version
入っているgitのversionを教えてくれる。

###clear もしくは　control + l
ターミナルの内容を消してくれる。


###gemのversionについて
gem 'rails', '~> 5.1.6'の~>は6以上ならアップデートしますよーって意味。
よって5.1.7が最新版ならrails -vとすると5.1.7と出る。

###bundle install　と　bundle updateについて
gemfileを書き換えたら基本はbundle installをする。
ただし、bundlerはgemファイルの差分を見つけてアップデートする仕組みなので、差分が多すぎるとエラーを出し、bundle updateをした方がいいですよーとメッセージを出す。
また、bundle updateは書かれてあるgemを１から読み取り、gemfile lockに書かれてある依存関係？とかを作り直してくれる。

###c9コマンドについて
awsではc9コマンドというのを使える。ただ、デフォルトでは入っていないので、インストールしなければいけない。
1. npm --version
でちゃんと機能するか確認
2. npm install -g c9
でインストールができる。
3. c9 --versionで確認。

###root 'application#hello'
これはapplicationコントローラーのhelloメソッドを呼び出してくださいねってこと。


##Git
$ git config --global user.name "Your Name"
$ git config --global user.email your.email@example.com

上記のコマンドは誰がコミットしたのか、どんな理由かコンタクトを取りたい、そんな時に使える。
必須ではない。git logなどで出てくる。

$ git init
initはinitializeの略。このコマンドによってgitを初期化する。

$ git status
gitに入っていないファイルが出てくる。

$ git add README.md
例えば上のようにすると、READMEファイルだけgitに入る。

$ git add -A
$ git add .

$ git add .は今いるディレクトリ以下のファイル全てをgitに入れることができる。
例えばconfigで上記のコマンドを行うと、config以下のファイルがgitに入る。
$ git add -Aはどこにいるか関係なく、全てのファイルがgitに入る。

$ git commit
$ git commit -m "Initialize repository"
git commitの場合は、別途操作が必要

$ git commit -a -m "Update Gemfile for Heroku"
これでgit add -A git commit -mをいっぺんにすることができる。

$ git log
これは誰がいつgitにコミットしたか、またメッセージを見ることができる。


公開鍵の作成
$ ssh-keygen
$ cat ~/.ssh/id_rsa.pub
公開鍵を持っていない場合は上記のコマンドで公開鍵を作ることができる。

##heroku

$ source <(curl -sL https://cdn.learnenough.com/heroku_install)
上記のコマンドでherokuコマンドが使えるようになる。

sqlite3とpostgresqlについて
sqlite3は開発用のデータベースである。そして、herokuは本番用のサーバーである。そのため、sqlite3を適用した状態でデプロイしようとすると、開発環境用のデータベース使うなと怒られる。


⌘　＋　p　でgo to anythingというファイル検索機能を使える。


$ heroku login --interactive
メールアドレスとパスワードを入れてログインする。

$ heroku keys:add
公開鍵の登録。とりあえずやっておく。

$ heroku create
このコマンドにより、本番用のサーバーが一瞬で立ち上がる。

$ git push heroku master
マスターブランチのソースコードをherokuに送りますよーってこと。

$ heroku rename rails-tutorial-hello
これによってherokuappのurlを変えることができる。
Windows10 から Raspberry pi に接続した

#VNCを使って接続しました

Raspberry pi model b + 
Windows10 pro

以下ダウンロードリンク
https://www.realvnc.com/en/connect/download/viewer/

1. 「Raspberry pi の設定」から インターフェイスに行ってください。
2. VNCを有効にして再起動してください。
3. そしたら右上のタスクバーにVNCのマークが出ると思います、そこをクリック
4. 出てきたWindowにIPアドレスが書いてあると思います、それをメモ
5. WindowsPC側でVNC Viewerを開きます。
6. 上の入力欄のところにさっきメモしておいたipアドレスを入力してEnterを押す
7. 出てきたWindowにusername と passwordを入力してokを押します、すると接続できます。

##詰まったところ
Raspberry pi 側でホストネームが「raspberrypi」だったのでずっとそれで接続しようとしてたけれどできないのでなぜかと思ったら、名前は「pi」だった。
username : pi
password : pass

これで接続。
Github actionsでgo mod download, test, lint

# Github Actions
https://github.co.jp/features/actions
GithubのCI/CDサービス

# モチベーション
現職ではほとんどcircleciで回しているが、Github actionsが便利ということを聞いたので試した。
go.modのキャッシュの問題などあり、実際にやってみて記事としてこれ持って来ればOKみたいのが見当たらず、
githubでpublic repoを徘徊したので、最低限自分にあったやり方をまとめておきたい

# workflow
stepなどはほぼ他のciサービスと同じだと思うので割愛
実際のyamlは以下

```github/workflows/ci.yaml
// 好きな名前
name: golang_ci
// フック
on: [push]

jobs:
  build:
    name: all
    runs-on: ubuntu-latest
    steps:
      # GOPATHなどのセットアップ
      - name: set up
        uses: actions/setup-go@v1
        with:
          go-version: 1.13
        id: go
      # repositoryの中身にアクセスするためのチェックアウト
      - name: checkout
        uses: actions/checkout@v1
      # cache store
      - name: cache
        uses: actions/cache@v1
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-
        # golang-ci
      - name: install lint
        run: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin v1.18.0
      - name: lint
        run: golangci-lint run
      - name: test
        run: go test ./... -v

```

基本的にactionを指定して環境を構築 -> 実行という流れ

参照できるactionは以下で
- public repository
- workflowと同一repository
- Dockerhubで公開されているDockerコンテナイメージ

# 感想
circleciと比べてみての感想になってしまうが以下のようなメリデメを感じた
### メリット
- [actions](https://github.com/actions)がOSSで定義されていてわかりやすい。自前のactionsも使えるのでいざとなればフォークして...
- やるべきではないという意見もあるかもしれないが、workflow配下をgithub GUI上で操作してコミット -> 反映というサイクルがまわしやすい(CIなど開発環境の整備のためのGithub上でのコミットは良いと思っている)
- 従量課金だが個人利用Freeであれば```2000分/月```まで無料枠らしいのでだいたいおさまる(https://github.co.jp/features/actions)
- 1repository 20並列の使用制限(https://help.github.com/ja/actions/automating-your-workflow-with-github-actions/workflow-syntax-for-github-actions#usage-limits)
- 他CIのように開発者tokenとかを外部に託さなくて良い(当たり前)

### デメリット
- 参考にできる実例が少ない
  これは仕方ない。実際に公開repositoryでgo.modのキャッシュ関連を```All Github```で調べても100件はなさそうだった
- sshがちょっとめんどくさそう
  workflowに変更を入れないとsshできない様子

手軽にsshしたいなと感じたくらいで、あとはCI構築のためには最適なGithub上でのtry and error、確認が手軽にできるのが嬉しい
今後個人repoなら使っていくかもしれない
コールバック

知らなかったんだけど、Authするときってコールバック必要でしょ？

それって、コールバック先のWebAPIを指定しないといけないと思ってたけど、ブラウザにコールバックでもよかったんだね。
つまり、サーバーを立てる必要がない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541101/1c790367-33e3-bfdb-ef40-bcbc69149eea.png)

こんな感じで、WinForm単品で、WebViewのNavigatedイベントでAuthCodeが取れるんだね。
引数のクラスを見れば、即取り方は分かると思います。VisualStudioだもの。

知らなかったわー。

今までは、自分のクラウドアプリにWebAPI用意して、xx/callbackみたいな口を用意してコールバック受けてって処理を進めていたわけです。
[UE4]テクスチャをD&Dでマテリアル生成

テクスチャをアクタに直接D&Dで勝手にマテリアル作成までやってくれます。
![Mat.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369485/097e0dcc-4901-e385-9c92-75e221a12f72.gif)
gfortranで落ちてifortで落ちないシンプルなコード。原因は不明

Fortranのコンパイラgfortranでよくわからない挙動が起きたので情報をシェアしたいと思います。

Mac:
gcc version 9.2.0 (Homebrew GCC 9.2.0) 
と
Ubuntu 16:
gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~16.04~ppa1) 
で確認しました。


```fortran:test.f90
program main
    implicit none
    complex(8)::g   
    g = 0d0 
    write(*,*) g**1d0
end program main
```

このコードは、gfortranでコンパイル：

```
gfortran test.f90 "-ffpe-trap=zero" -O0
```
するとなぜか

```
Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.

Backtrace for this error:
#0  0x10bb51f3d
#1  0x10bb5134d
#2  0x7fff6c701b5c
Floating point exception: 8
```
というエラーで落ちます。

ifortだと落ちません。
原因は不明です。

```
 gfortran test.f90 "-ffpe-trap=invalid" -O0
```

だと

```
Program received signal SIGFPE: Floating-point exception - erroneous arithmetic operation.

Backtrace for this error:
#0  0x10142ef3d
#1  0x10142e34d
#2  0x7fff6c701b5c
#3  0x7fff6c6924cf
#4  0x101423e1b
#5  0x101423e9e

```
と落ちます。


何が原因なのでしょう。
tlog

* https://github.com/Scribery/tlog

```sh:centos8
yum install -y tlog
```

```sh:記録
tlog-rec --writer=file --file-path=tlog.log
```

```sh:終了
# 他の方法あると思う・・・。
killall tlog-rec
```


```sh:再生
tlog-play -i tlog.log
```
大規模開発でスクラムを取り入れてみた

エンジニア の @fujii_masayuki です。フォトクリエイトでPMをしています。

この記事は [フォトクリエイト Advent Calendar 2019](https://qiita.com/advent-calendar/2019/photocreate) の 1日目 の記事です。

#はじめに
フォトクリエイトでは写真の販売を目的としたサイトをいくつか運営していますが、
その中で園・スクールを対象にしたスナップスナップ([snapsnap.jp](https://snapsnap.jp))というサイトを昨年から今年にかけてリニューアルしました。
そのプロジェクトで今回採った開発プロセスはウォーターフォールとスクラムを組み合わせて実施をしたのですが、そこで学んだこと、苦労した事を書いていきたいと思います。

※2019/12/23追記
スクラムの詳細な取り組み内容を [大規模開発でスクラムを取り入れてみた～実践編～](https://qiita.com/fujii_masayuki/items/43b59d8e83bdd963a7de) に記載しました。
よければこちらも併せてご覧ください。

#プロジェクトの概要
スナップスナップは 12 年にわたる度重なる改修が入っており、それらの仕様のすべてを網羅して知る人もいない老朽化した状況でした。
その中で以下の点などが課題となっていました。

 - 他のシステムと仕組みが分離できておらず改修がしづらい
 - PC・スマホが別仕様、別画面で作られているため、１つの機能改修で2倍の工数がかかる
 - カートが共通化されていない（商材によって別カートになっている）ため、カートに手を入れる際も工数が倍かかる

これらを解消するため、サイトのフルリニューアルを行いました。

##やった事
- システムの分離
- PC・スマホをレスポンシブで構築
- 購入導線の見直し

##採用した技術
せっかくリニューアルするのでなるべくモダンな構成で構築をしたいとの思いからNuxt.js+PHPで構築する事を決めました。

- フロント：Vue.js
- API：Laravel
- DB：Aurora
- インフラ：AWS
- ドキュメント管理：GitHub
- プロジェクト管理：Instagantt、Jira

##全体の規模感

- 工数：100人月以上
- 関わった人数：10人以上
    - プロダクトマネージャー（PDM）
    - プロジェクトマネージャー（PM）
    - デザイナー
    - フロントエンドエンジニア（FE）
    - サーバーサイドエンジニア（SE）
    - SRE
    - テックリード
- 開発期間：10ヶ月

#プロジェクトの課題
当初、弊社ではフロントエンドエンジニア（FE）という職種がありませんでした。
というのもレガシーシステムではフロントもAPIも全てPHPで書かれているため、役割の分担としてはPHPエンジニアとHTML & JSのコーダーで別れていました。
なのでコーダーがフロントエンジニアに職種転換をするという決意のもとで、１からVue.jsを勉強しながらのスタートとなりました。

まったくの手探りで開発がスタートしたわけですが、やる気があるとはいえ、プロトタイプを作ってみたもののしっくりくるものとは言えず、
開発の難易度・規模感から不確実性が高いスケジューリングとなりプロジェクト全体には不安感が広がっていました。

ウォーターフォールは最初にすべての仕様とタスクが明確になっていて初めて正確な見積ができるのですが、初めての言語での開発という事と、エンジニアの大半が業務委託という事もあり正確な見積はできませんでした。
その中で出てきたのがスクラムでプロジェクトを進めてみるという案でした。

#ウォーターフォールからスクラムへの転換
ステークホルダーとの納期の約束や、外部連携先とのテストも含めて考えるとすべての工程をスクラムで組むわけにはいきません。
納期とテストの工程のスケジュールを極力ずらさずに、かつメンバーのモチベーションが保てるように開発の工程のみをスクラムで組むように組み替えました。

【変更目的】
　・ 役員やPDMに正しいリリース判断をしてもらうため
　・ 開発チームのモチベーションを維持・向上するため

【変わる事】
　・実績に基づいて予測をたてるため、スケジュールがより正確になる
　・作業を詰め込まないため、スケジュールの冗長化を招きやすい  
　⇒リリースする機能を減らしたり増やしたりすることでコントロールする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309292/271fb5d7-3293-f1b9-c63c-8162b91c81c5.png)

#スクラムの内容
- スプリントは1週間単位
- 1機能を数スプリントで開発
- スプリント内で機能が完成しないため、スプリント毎に目標を決める
- 全体のマイルストーンは先に決めておく


#良かった点、苦労した点

##良かったこと

- エンジニアの心理的な負担が減少
自分たちのペースで1スプリントの内容を決めるため、あまり無理をし過ぎないスプリント設計にできたこと。
とはいえ、技術的な難易度が高い個所、開発ボリュームが大きい個所はあるため、それもエンジニア自身が織り込んで次のスプリント設計をする事で、命令ではなく自ら改善策と目標を決めて動くため心理的な負担は減ったと思う。  
  
- ベロシティを計る事で、次週の指標とすることができた
自分たちの開発力を数値化する事が出来たおかげで、次週どの程度できるのかが明確になった。

## 苦労した事
- ベロシティが安定しなかった  
スプリントの設計を機能単位ではなくした事で、難易度が高いフェーズを含むスプリントのベロシティが下がる結果に。  
そのベロシティを参考に次週を組むと難易度が低い個所は進みが良いため参考になりづらい。 



#最後に
会社全体としてはよりプロダクトをより強くするために、PDMの組織を開発組織内に置き、PDMとエンジニアが一体となって開発に取り組むようにしました。
まだまだ組織と仕組みを変えている途中ではありますが、未熟だからこそ新しい事にチャレンジするという精神で取り組みをしています。

スクラム自体は本来は継続的なサービスの向上を目的にプチリリースを何度も繰り返す手法としてスプリントを導入・設計する事が理想だと思います。
プロダクトを継続して開発していく手法としては最適で、今後も取り入れながら進めたいと考えています。
今回のプロジェクトはその良い練習になったと思います。

スクラムに限らず新しい事に前向きに一緒に取り組める方を採用しております。
少しでもご興味をお持ちいただけたようでしたら、人事部門の担当者 [twitter: @tetsunosuke](https://twitter.com/tetsunosuke) へお知らせください。

明日の記事は @andoshin11さんによる [SSRとCookie Forwardingの闇](https://blog.andoshin11.me/posts/cookie-forwarding-on-ssr)です。
なぜメタゲノム解析するのか？

「そこにメタゲノムデータがあるからだ（大嘘）」

##はじめに
メタゲノマーによるメタゲノマーの為のアドベントカレンダーではありますが、アドベントカレンダー初日なので、ここにいざわーるど解釈の「メタゲノム解析って何？」的なポエム記事を書いておきます。

##そもそも「メタゲノム解析」って何？

###遺伝子を全部調べたい

この記事を読んでいる方なら「ヒトゲノム解析計画」という言葉を一度は聞いたことがあるかもしれません。「ゲノム」は「遺伝子全部」のような意味で、「ヒトゲノム解析計画」自体を平易な日本語にすれば「ヒトの遺伝子を全部を調べる計画」のような意味です。
ヒト以外にも様々な生物に関して「遺伝子を全部を調べる計画」が行われていますが、ある生物の遺伝子を全部調べる利点として、創薬、医学や、生物工学など様々な応用研究の基盤になることが期待されています。

さて、問題の「メタゲノム解析」についてですが、特に微生物に対して使われることの多い手法です。
「メタゲノム解析」の「メタ」は「meta-」という接頭語であり、「高次的な〜」みたいな意味を持っています。小説なんかで登場人物する読者を意識したような発言を「メタ発言」と言いますがあのメタです。
通常の「ゲノム解析」が単一の生物の遺伝子を調べる手法だったのに対し、「メタゲノム解析」の「メタ」は「高次」≒「多種多様な微生物」の意味と取れるでしょう。
つまり、「メタゲノム解析」は「多種多様な微生物の遺伝子を全部調べる」という感じの意味になります。


###なぜメタゲノム解析するのか？

肉眼では見ることができない微生物の研究には、長らく培養法が用いられてきましたが、土壌、海洋、ヒト腸内など様々環境に存在する微生物の中には、培養が難しいものも多く、環境微生物の網羅的な把握は困難でした。

そんななか、30年ほど前からのPCRやDNAシークエンシングなどの「遺伝子を調べる方法」が発展したことにより、ある環境サンプル（土壌なら土から、海洋なら海水から、ヒト腸内なら糞便から）から多様な微生物の遺伝子をより網羅的に調べる、つまり「メタゲノム解析」が可能になりました。

培養法による限られた微生物の研究からも人類に有用な物質が得られていたため、より多様な微生物を網羅的に調べることができる「メタゲノム解析」なら、創薬、医学や、生物工学等々の応用研究にの基礎となる有用な知見が多く得られるはずです。
メタゲノム解析、やるしかない！！！！！！！（ﾊﾞﾊﾞｰﾝ

##メタゲノム解析やるしかない...では次は？

メタゲノム解析計画を成功させるため、既にある知見を活かして、必要なサンプル数、大量のシークエンスデータ、大規模計算環境などを用意して解析を始めるのですが、未知微生物との遭遇などにより想定していなかった問題が発生したりします。そのため当初描いていた最終的な目標までは結構曲がりくねった道を行くことになったりします。

そんな、先人が曲がりくねった道を行った先に見た結果、また後人達がよりまっすぐ目標に到達できるようにするために作られたツールなどがこのアドベントカレンダーでは紹介されていくことでしょう。

以降24日間（この記事を書いている時にはまだ3,4日分くらいのエントリーしかなく悲しいことになりそうですが）にわたるメタゲノマー達の技術/論文紹介などの記事を参考にメタゲノム解析、やっていきましょう。
アクセシビリティ(a11y)対応の 「HTMLを書くとき」の自分メモ


## a11yの必要性

* 過去記事
    * https://qiita.com/SatoshiMukainakano/items/6a23f4ca90579eeff277
    * https://qiita.com/SatoshiMukainakano/items/f38b71d99698576696c9
    * ワールドワイドで見たら、より厳しいとこ多数
    * 自分だって、いつケガしたり、障害もったり、するかわからない
    * ケガや障害じゃなくても、公共の場の利用でもヒントになる


## HTML書くとき

※書き終わったあとのコードを振り返るときにも。

### (1) コンテンツのランドマーク

* どのセクションにも属していない `header` タグ or `role="banner"`
* どのセクションにも属していない `footer` タグ or `role="contentinfo"`
* 文法上正しい位置にある `main` タグ or `role="main"`

#### メモ

* 原則として、ページを通して1箇所
* これら3つは互いに、どれかの子孫要素にも、どれかの祖先要素にもなっていない
* 「ここを探索できれば一発」的に、「共通ヘッダ」「共通フッタ」「コンテンツ主旨」 を示す

### (2) 部品のランドマーク

* `nav` タグ or `role="navigation"`
* 検索のためのフォーム ( `role="search"` )
* データ送信・操作のためのフォーム ( `role="form"` )

#### メモ

* コンテキスト、コンテンツ の並びによって、複数あっていいケースあり

### (3) 見出し・セクション

* `h1-6` ( `h1`, `h2`, `h3`, `h4`, `h5`, `h6` ) タグ
* `aside` タグ or `role="complementary"`
* `article` タグ
* `section` タグ

#### メモ

* 「見出しをジャンプ」していくことで、そのページが伝えたいアウトラインを素早く巡行できる状態を目指す
    * 本文しかないならともかく、それ以外のものもある中でいちいち全部をめぐってられない
    * h1-6タグ でマークアップされた要素をジャンプしていく「見出しジャンプ」「見出しナビゲーション」 機能を活用
        * 例・VoiceOver ： https://website-usability.info/2010/11/entry_101123.html
        * 例・TalkBack ： https://support.google.com/accessibility/android/answer/6006598?hl=ja
        * 例・NVDA ： http://nvdajp.osdn.jp/howto/manual/nvda_commands.html
* 見出し【以外】を全部なくしたら、「コンテンツのアウトライン」がうまく描けている状態

#### 注意

* HTML LS文法上で厳密に言えば、だいぶ語弊が残る
* あくまで、現時点の実装を踏まえた「早見」として
* 2019年11月時点では アウトラインアルゴリズム を踏襲した ブラウザ・支援技術 は見当たらない、とされる


### (4) 他とつなげる

* 他のページへの遷移
    * `a` タグ
        * aタグ 以外のタグで「リンク」を装うのは原則的に非推奨
        * やむない場合にのみ、 `role="link"` を活用
        * `target="_blank"` には `rel="noopener"` を併設されたい
        * なるべくラベルだけでリンク先の 主旨・概要 を示したい
* フォーム
    * ラベル付け必須
    * エラーをしっかり明記
* 埋め込みコンテンツ
    * 代替テキストなり、代替コンテンツなり、補助情報なり
* 外部リソース
    * `link` タグ、 `meta` タグ、 OGP関連、アクセス解析系
* スクリプト


### (5) その他

HTML LS や WAI-ARIA を有効に活用

* リスト
* テキストレベル
* 動的に内容を変更したことを示す


## 参考にしたもの（一部）

* https://waic.jp/docs/WCAG20/Overview.html
* https://html.spec.whatwg.org/multipage/
* https://momdo.github.io/html/
* https://developer.mozilla.org/ja/docs/Web/Accessibility
* http://honttoni.blog74.fc2.com/blog-entry-61.html
* https://shibe97.tumblr.com/post/121266132377/html5のアウトラインを極めるための6つのルール
* https://developer.mozilla.org/ja/docs/Web/Guide/HTML/Using_HTML_sections_and_outlines
* http://www.html5-memo.com/html5/html5_03/
* ツール： https://gsnedders.html5.org/outliner/
* https://reliphone.jp/disabilities-possibilities/
* http://ommyzfactory.cocolog-nifty.com/blog/2019/10/post-a30587.html



[EOF]