OmniAICreator/Qiita-1.07M huggingface dataset:
リモート先も満足できるTV会議について

# はじめに
* 遠い拠点のメンバーと毎週会議を行いたい場合、どうしても何回かはTV会議を行うことになる。
* その際、リモート先では伝わらない状況がいくつか発生したため改良を繰り返して満足してもらえたTV会議の方法をまとめておく
    * 伝わらない状況
        * 会議室の雰囲気（メンバー数や表情など）

# システム構成
* 会議用マイク
* Webカメラ
* THETA系全方位カメラ（RICOH R Development Kit）
* ノートPC
    * アプリケーション
        * Slack/Microsoft Teams
            * リモート会議実施用
        * OBS
             * 映像のミキシング用（後述）
* ![IMG_4884.JPG](https://qiita-image-store.s3.amazonaws.com/0/44076/05729188-f068-e371-1ee5-119daefc26f4.jpeg)


# 実施方法
* ホストはSlack/Microsoft Teamsで会議を立ち上げる
    * SlackはSlackコール
    * リモート先の人は会議に参加してもらう
* ホストはOBSを起動してシーン上にキャプチャデバイスとして以下の２カメラを配置する
    * Webカメラ
    * THETA系全方位カメラ
    * ![IMG_4883.JPG](https://qiita-image-store.s3.amazonaws.com/0/44076/cbd52a9d-611b-8d19-4b6c-f351e3c51056.jpeg)
* ホストは、画面共有機能を使用して「OBS」を表示するようにする
    * リモート先でOBSの画面が共有される

# 会議中の操作
* 資料が提示された場合は、Webカメラをズーム
    * <img width="1325" alt="スクリーンショット 2018-09-26 16.39.24.png" src="https://qiita-image-store.s3.amazonaws.com/0/44076/8e92f6db-6654-3161-6072-efec8ece5045.png">
* 議論になったときは、全方位カメラをズーム
    * <img width="1325" alt="スクリーンショット 2018-09-26 16.39.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/44076/b3c89920-6968-cd1a-e8f7-3b50a1cad250.png">
* OBSはリアルタイムでソースの位置・サイズを変更できるのでこのようなことがカンタンにできます。

# わかったこと
* カメラを使うからカメラから選ぶ必要はない！
    * 画面共有という方法もある

# さいごに
* Webカメラだけでは資料しか見れず、全方位カメラだけでは資料が読めない、でも会議システムは１カメラしか使えない、、、という話から一緒に出すカンタンな方法はないか？という議論で生まれたのがこの手法でした。
* 特に複雑なことはしていないのですが実際に使ってみるとリモート先からは何もしてなくても雰囲気がわかるし画面の切り替えの煩わしさもないので良くなったと好評でした。
rails c にてエラーが出た時の解決策・・はダメでした。

##rails cの実行結果

```terminal
Cannot read termcap database; 
using dumb terminal settings.
irb>>
```
事の始まりは`rails c`を実行した際に出現する、エラーとも受け取れかねない上記二行メッセージの存在である。
`dumb`は英語で「バカ・間抜け」の意味がある。`using dumb terminal settings`とは「クソみたいなterminalの設定使ってるよ」と言われている様なもの。
ここの場合では違うような気もするがひとまず、これは解決しなければ`dumb`なのかもしれないということでググってみた。

##readlineのインストールが必要
最初にhitしたサイトでは「`rails s`をやった後に`rails c`を行うとダメだ」との記述があったが再起動したのちに`rails c`のみを行っても結果が変わらなかったので却下。
[IRB history not working with Ruby 2.3.0](https://stackoverflow.com/questions/37847822/irb-history-not-working-with-ruby-2-3-0/37847933#37847933)のサイトより

>
Using Homebrew
>
rbenv automatically detects homebrew and looks in it for readline, so, if you're using Homebrew and irb history doesn't work, you either haven't installed readline or you built your Ruby before you installed readline.
>
```terminal
brew install readline if it isn't installed already
rbenv uninstall 2.3.0
rbenv install 2.3.0
```

Rubyをインストールする前に、brewにてreadlineをインストールしてないとエラーが出るとの趣旨。
readlineは既にあったので、rubyの再インストールを実行。

##rubyインストールでエラー

```terminal
The Ruby zlib extension was not compiled.
ERROR: Ruby install aborted due to missing extensions
Configure options used:
  --prefix=/Users/Natsuki/.rbenv/versions/2.5.1
  --with-openssl-dir=/usr/local/opt/openssl
  --with-readline-dir=/usr/local/opt/readline
  CC=clang
  CFLAGS= -O3 -Wno-error=shorten-64-to-32 
  LDFLAGS=-L/Users/Natsuki/.rbenv/versions/2.5.1/lib 
  CPPFLAGS=-I/Users/Natsuki/.rbenv/versions/2.5.1/include 
```
以前も遭遇したことのあるエラーが再び発生。通常では発生し得ないエラーだそうで、何らかの原因あるいは設定ミス？でMac OSユーザーに降りかかる災いの一種なので
[Ruby zlib extension was not compiled OS X 10.9.5 #832](https://github.com/rbenv/ruby-build/issues/832)のサイトより

>You would literally do these commands in the terminal:
>
```
brew install zlib
RUBY_CONFIGURE_OPTS="--with-zlib-dir=$(brew --prefix zlib)" rbenv install 2.5.1
```

`zlib`は前回インストールしていたので二行目のコマンドのみを実行。

##ruby インストール成功

```terminal
ruby -v
ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-darwin17]
```
無事にrubyの再インストール成功。さて、これで`rails c`のエラーは解決出来たのか・・？

```terminal
watasi-no-MacBook-Pro-4:rails_sample Watashida$ rails c
-bash: /Users/Watashida/.rbenv/shims/rails: No such file or directory
```

？！ railsの霊圧が・・・消えた？

##rails の再インストール

`gem install rails`を実行した後に`bundle install`を実行してrailsを復元。
再び問題が解決したか試すと

```terminal
$ rails c
  Cannot read termcap database;
  using dumb terminal settings.
```

これは・・ダメですね。
`rails c`が動かないわけではないので、これはこれでひとまず放置します。。

##後日談
その後何度か`rails c`を用いてコンソール画面を開くたびに気付いたのが、上述のエラー（？）とも受け取れる記述が出る場合と出ない場合があることでした。
厳密に何が起きているのかは詳しく調べる必要がありそうですが、出たり出なかったりする以上はさした問題ではないと思われます。
有用なコーディングスタイルの一覧

# はじめに
都度ググるのが面倒なので, 参考になるコーディングスタイルのリンクを言語ごとにまとめておく。
対象言語は, C, C++, C#, Java, Python のみです。

## "C"
- [C STYLE GUIDE (NASA)](http://homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf)

## "C++"
- [Modern C++ Coding Guidelines](https://github.com/Microsoft/AirSim/blob/master/docs/coding_guidelines.md)
- [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
- [Google C++ Style Guide (Japanese)](https://ttsuki.github.io/styleguide/cppguide.ja.html)

## "C#"
- [C# のコーディング規則 (C# プログラミング ガイド)](https://docs.microsoft.com/ja-jp/dotnet/csharp/programming-guide/inside-a-program/coding-conventions)
- [C♯ Coding Style Guide Version 0.3](http://www.icsharpcode.net/TechNotes/SharpDevelopCodingStyle03.pdf)

## "Python"
- [Deprecated Google Python Style Guide](https://google.github.io/styleguide/pyguide.html)
- [PEP 8 -- Style Guide for Python Code](https://www.python.org/dev/peps/pep-0008/)

## "Java"
- [Google Java Style Guide](http://google.github.io/styleguide/javaguide.html)
別docker-compose同士のネットワークを繋げる方法

## 概要

docker-composeを利用して、Vue.jsのコンテナ、APIモックサーバのコンテナを作成して、開発をしているのですが、gitリポジトリを別にしようとするとdocker-compose.ymlを分割→ネットワークが別になってコンテナ内からAPIへアクセスできなくなって困った。ので、どうにかならないか調べて見ました。


## 解決

docker-compose で別の docker-compose.yml で作ったコンテナとリンクする (ネットワークを繋げる)
https://qiita.com/reneice/items/20e981062b093264cd0a

上記記事がとても参考になりました。感謝！

参考までにdocker-compose.ymlの定義です。

Vue.jsやモックサーバのコンテナ構築については下記をご参考ください。

DockerでVue.js+TypeScript開発環境を構築する
https://qiita.com/kai_kou/items/d581a9f8f3ee8605aed1

Dockerとapi blueprint+aglio+drakovを使ってAPI開発を楽にする
https://qiita.com/kai_kou/items/feca8974f3967a285ff4


### APIのdocker-compose.yml

```yml:docker-compose.yml
version: '3'

services:
  drakov:
    build: .
    ports:
      - "3001:3001"
    volumes:
      - "./docs:/projects"
    tty: true
    command: drakov -f "**/*.md" --public --watch --p 3001
```

### Vue.js側

```yml:docker-compose.yml
version: '3'

services:
  app:
    build: .
    ports:
      - "8080:8080"
    volumes:
      - ".:/projects"
    tty: true
    networks:
      - [APIのネットワーク名]
networks:
    [APIのネットワーク名]:
      external: true
```

[APIのネットワーク名]はAPIのコンテナを実行後、以下コマンドで取得できるネットワークのリストの```NAME``` になります。

```sh
> docker network ls

NETWORK ID          NAME                    DRIVER              SCOPE
xxxxxxxxxxxx        xxxxxx_default          bridge              local
```

これで、Vue.jsのコンテナ内からAPIモックサーバのコンテナへアクセスできるようになりました。

```sh
> curl http://xxxxxx_drakov_1:3001/
```

やったぜ。


## 参考

docker-compose で別の docker-compose.yml で作ったコンテナとリンクする (ネットワークを繋げる)
https://qiita.com/reneice/items/20e981062b093264cd0a

DockerでVue.js+TypeScript開発環境を構築する
https://qiita.com/kai_kou/items/d581a9f8f3ee8605aed1

Dockerとapi blueprint+aglio+drakovを使ってAPI開発を楽にする
https://qiita.com/kai_kou/items/feca8974f3967a285ff4

Vue.js+TypeScriptで開発するときの参考記事まとめ
https://qiita.com/kai_kou/items/19b494a41023d84bacc7
php-master-changes 2018-09-27

# 2018-09-27
## petk: Remove unused and untouched ext/libmbfl/tests files
- https://github.com/php/php-src/commit/a4102e1bc31fcc2f77610d8430fbf90f7a8b6206
- ext/mbstring の libmbfl/tests を削除
- libmbfl は fork して php-src へバンドルされてる奴だけれど、テストは phpt を使っていて元々の tests は使われていなかった

## petk: [ci skip] Sync licenses
- https://github.com/php/php-src/commit/6b324bf845302705d062bfb410552a9b95200562
- バイナリ再配布にあたって考慮が必要な各ファイルのライセンスを記したファイル、README.REDIST.BINS を現状にあわせ修正
- ext/zip/lib は[バンドルされなくなった](https://qiita.com/sj-i/items/951e46693d1af57adf2a#nikic-remove-bundled-libzip)ので削除
- [libzip から抜き出されている部分を含む](https://github.com/php/php-src/blob/169d4545931a43df258608c6cfb59b3e4bb92776/ext/phar/zip.c#L90) ext/phar/zip.c のための記述が必要なので追加

## petk: Rename ext/snmp/tests/bigtest.sh to bigtest
- https://github.com/php/php-src/commit/390b74ee34ac567cab7d6b07b130a16504bbc43c
- ext/snmp の ext/snmp/tests/bigtest.sh を ext/snmp/tests/bigtest へリネーム
- テスト実行時自動生成されるスクリプトファイルで .gitignore により [\*\*/tests/\*\*/*.sh が指定されている](https://github.com/php/php-src/blob/master/.gitignore#L197)ものがあり、これとの区別用

## nikic: Fix missing access errors for guarded properties
- https://github.com/php/php-src/commit/5a4cb3edde32a6cc4bce6439abea21f3e6b4bbf6
- マジックメソッド経由で本来アクセスできないスコープのプロパティへアクセスしようとする際に例外を投げるよう修正
- 元々は何もしないという挙動だったりした
    - https://3v4l.org/Up6C3
    - https://3v4l.org/TftnR
    - https://3v4l.org/FHliH
- が、それでは[マジックメソッドでない場合の挙動](https://3v4l.org/QOWYv)と整合性がとれない
- 存在しないプロパティへアクセスしようとすると ```__get()``` や ```__set()``` が呼び出されるが、マジックメソッドの再帰的な呼び出しは実装により[防がれており](https://github.com/php/php-src/blob/49b92446d780bcb750d65148bc4ad1519bf66fb3/Zend/zend_object_handlers.c#L721)、起きた場合はマジックメソッドが存在しないよう振る舞う、という挙動になっている
- 修正自体はこのチェックで呼び出しが防がれた際、アクセス違反を検知して例外を投げるようにした、というもの
linuxでの上書きフォーマット【備忘録】

### Linuxでファイルシステムの上書きフォーマット(ファイル完全消去)をするには
shredコマンドを使う
`sudo shred /dev/sda` のように

#### 1. フォーマットするデバイスのパスを調べる
`sudo blkid`

```console
$ sudo blkid
/dev/sda1: LABEL="SYSTEM_DRV" UUID="48AE6E41AE6E2820" TYPE="ntfs" PARTUUID="c4cb03ac-01"
/dev/sda2: LABEL="Windows7_OS" UUID="44B677ECB677DD3C" TYPE="ntfs" PARTUUID="c4cb03ac-02"
/dev/sda3: UUID="4415f532-e503-4ea0-bb1d-6096b37bf550" TYPE="ext4" PARTUUID="c4cb03ac-03"
/dev/sda4: LABEL="shere" UUID="3DD4045025015F2A" TYPE="ntfs" PTTYPE="dos" PARTUUID="c4cb03ac-04"
/dev/sdb1: LABEL="My Passport" UUID="F474B7AA74B76DCC" TYPE="ntfs" PARTUUID="cb189578-01"
```

#### 2. shredコマンドを実行する  
オプションとして
+ `-n [任意の数]` [任意の数]文だけランダムな上書きを実行する
+ `-v` 進捗状況を表示する
がある

```console
$ sudo shred -n 3 -v /dev/sdb
Rubyの繰り返し処理（ループ処理）


#１.繰り返し処理の必要性
プログラミングでは同じ処理を何度も行いたいという場面が出てきます。
その時、何度も同じコードを書き続けるというのは無駄に時間をかけてしまうことになります。

そこで、繰り返し処理（ループ処理）という機能を使うことで、同じコードを書き続けることなく、***効率よくコードを書いて同じ処理を何度も実行する***ことができます。

#2.よく使われる繰り返し処理

###eachメソッド

```ruby:文法
オブジェクト.each do |変数|
  #実行する処理
end
```
＜使い方例＞
オブジェクトに含まれる要素を順番に変数に格納して、処理を実行します。オブジェクトに含まれる要素がなくなったら終了です。

＜実践＞
５回処理を繰り返してみます。
(1..5)で変数が最初の値から最後の値になるまで、実行したい処理が行われます。
iを変数として置きます。

```ruby:５回繰り返す場合

(1..5).each do |i|
  puts "繰り返します"
end
```
"繰り返します"が５回出力されます。

```
$ ruby ファイル名.rb 
繰り返します
繰り返します
繰り返します
繰り返します
繰り返します
```

###while文


```ruby:文法
while　条件式　do　 #doは省略可能
  #実行したい処理
end
```
＜使い方例＞
条件式（不等号＜ ＞ などをよく使う）が成立する間は繰り返し処理がされます。

＜実践＞
５回処理を繰り返してみます。
iを変数として置きます。
i += 1　というのは変数iに１を足す処理になります。（自己代入演算子）

```ruby:５回繰り返す場合
i = 0
 while i <= 5 do
  puts "繰り返します"
 i += 1
end
```
"繰り返します"が５回出力されます。

```
$ ruby ファイル名.rb 
繰り返します
繰り返します
繰り返します
繰り返します
繰り返します
```



###for文



```ruby:文法
for 変数 in　オブジェクト　do  #doは省略可能
  #実行したい処理
end
```
＜使い方例＞
オブジェクトの中に数値（1..5）などを入れると変数が最初の値から最後の値になるまで、実行したい処理が行われます。

＜実践＞
５回処理を繰り返してみます。
iを変数として置きます。

```ruby:５回繰り返す場合
i = 0
for i in 1..5
  puts "繰り返します"
 i += 1
end
```

"繰り返します"が５回出力されます。

```
$ ruby ファイル名.rb 
繰り返します
繰り返します
繰り返します
繰り返します
繰り返します
```

#3.繰り返し処理の応用

１から20までの数字を数える中で、３の倍数で「ワン」、５の倍数で「にゃー」、１５の倍数で「ガオ！」と表示される繰り返し処理を作ってみる。

---
###他に使う機能　if文
条件式が正しかった場合（真だった場合）に処理が実行される

```ruby:if文
if 条件式
  #条件式が正しい時に実行する処理
elsif 条件式
  #条件式が正しい時に実行する処理
else
  #if elsif　の条件式が合わなかった時に実行する処理
end

```


elsif　
・ifが条件式に合わず、elsif　に記載の条件式が正しかった場合（真だった場合）に処理が実行される
else 
・ifまたはelsifにひっかからなかったら処理が実行される

---

早速、eachメソッドで記述します。
まず考えるべきことは、１５の倍数は１５で割ると剰余が０になるということに着目します。
それを応用し、％で剰余を求めることができるので、０になる数字を条件式で探します。
（「変数％数字」で剰余が出てきます。例えば、「１２％５」は２になります。）
３の倍数、５の倍数も同様です。

```ruby:eachメソッドで記述した場合
(1..20).each do |i|
  if i%15 == 0
    puts"ガオ！"
  elsif i%3 == 0
    puts"ワン"
  elsif i%5 == 0
    puts"にゃー"
  else
    puts i
  end
end
```
```:結果
$ ruby ファイル名.rb 
1
2
ワン
4
にゃー
ワン
7
8
ワン
にゃー
11
ワン
13
14
ガオ！
16
17
ワン
19
にゃー
```
続いて、for文で記述します。

```ruby:for文で記述した場合
i = 0
for i in 1..20 do
  if i%15 == 0
    puts"ガオ！"
  elsif i%3 == 0
    puts"ワン"
  elsif i%5 == 0
    puts"にゃー"
  else
    puts i
  end
end
```

```:結果
$ ruby ファイル名.rb 
1
2
ワン
4
にゃー
ワン
7
8
ワン
にゃー
11
ワン
13
14
ガオ！
16
17
ワン
19
にゃー
```

では続いてwhile文で記述したいと思います。
性質上、記述が若干異なります。


```ruby:while文で記述した場合
i = 1　　#変数は処理を始めたい数値にすること
while i <= 20
  if i%15 == 0
    puts"ガオ！"
  elsif i%3 == 0
    puts"ワン"
  elsif i%5 == 0
    puts"にゃー"
  else
    puts i
  end
  i += 1 #変数に１を追加するの重要！
end
```

```:結果
$ ruby ファイル名.rb 
1
2
ワン
4
にゃー
ワン
7
8
ワン
にゃー
11
ワン
13
14
ガオ！
16
17
ワン
19
にゃー
```

#4.注意点

###・上から順番に実行されるので優先したい処理を先に記述する
　　・例えば１５の倍数と３の倍数で１５の倍数を優先させるのであれば１５の倍数の記述を３の倍数よりも上にかく
###・繰り返し処理は変数がどのような状態になれば終わるのかを確認すること
　　・繰り返すたびに変数に１を追加しないと永遠にループしてしまうことがあるため
省略可能な引数

C# 4.0から省略可能な引数が利用可能。
クラスモジュールの関数に省略可能な引数を追加するという修正をした場合、呼び出し元のリビルドが必要。
クラスモジュールのみ入れ替えると、「引数が○○個のメソッドがありません」の例外が発生する。
他の呼び出し元に影響なく修正できると思いがちなので注意。

「A.exeとB.exeで呼び出している関数に省略可能な引数を追加し、クラスモジュールとAのモジュールを差し替え」
上記の場合、B.exeを実行すると例外が発生する。
Any()、Count、Count()の使用方法

Any()　・・・LINQのメソッド。Enumerable型で使用できる。１件以上要素があるか確認する場合、Count()より速い。
Count　・・・List型のプロパティ。値として持っているので数えに行かない。
Count()　・・・LINQのメソッド。Enumerable型で使用できる。 ~~その都度数えに行くので、その分が遅い。~~　対象が`ICollection<TSource>`の場合は数えに行かない。対象のCountプロパティを返す。

Countプロパティが使用できない場合、ToList()でListに変換する手もあり。


~~■まとめ
基本的にCount()は使用しない
→リストにある数分だけループしながらカウントするため
→処理に時間がかかる
Any()、Countの方が処理が速いためこちらを推奨する~~
[PyCon ポスター] NLP（自然言語処理）初心者のための単語分割/品詞タグ付けツールの紹介

**ポスターセッション in PyCon JP 2018**
---
今年の [PyCon JP 2018](https://pycon.jp/2018/) で発表したポスターです。
![pycon2018_a1.jpg](https://qiita-image-store.s3.amazonaws.com/0/257779/a489215a-dbc1-a8f6-a1df-3d406c8d8965.jpeg)

**Qiita**
---
- [nagisa: RNNによる日本語単語分割・品詞タグ付けツール] (https://qiita.com/taishi-i/items/5b9275a606b392f7f58e)

**GitHub**
---
- https://github.com/taishi-i/nagisa

**参考リンク**
---
- [Pythonで動く形態素解析ツール「nagisa」を使ってみた] (https://upura.hatenablog.com/entry/2018/09/18/203540)
macOS Mojave では FileMaker 14 でファイルを開こうとすると落ちる

# macOS Mojave
つい先日正式にリリースされた macOS の最新版です。
[macOS Mojave \- Apple（日本）](https://www.apple.com/jp/macos/mojave/)

# FileMaker 14 でファイルを起動しようとすると落ちる
Mojave で FileMaker 14 を用いる際、アプリケーション自体の起動はできますが[^1]、データベースファイルを開こうとすると 100% 落ちます。

# どうするか
掲示板にはこの現象の書き込みがいくつか見受けられました。例えば下記の内容などです。

[Filemaker crashing since Mojave update](https://community.filemaker.com/thread/190895)

この内容以外でもそうなのですが、解決するためには「バージョンを上げろ」という身も蓋もない内容が並んでいました。いやそりゃそうなのですが、種々の事情により[^2]そう簡単に上げることが難しい場合もあるわけで、悩ましい問題です。

# 結論
結論としては、FileMaker 自体のバージョンを上げる方法以外ですと、Mojave にアップデートしないか、FileMaker 用に別環境を作る、などでしょうか。

もはや 14 は Webページ にも言及がないくらいの古いバージョンですので、自らで何とかするしかないような気がします。

[^1]: たまにできないときもある
[^2]: 特に FileMaker Server とともに運用している場合
Slack — APIに使う「チャンネルID」を取得する方法


# チャンネルIDとは

API には、チャンネル名をそのまま渡せない。
チャンネルごとに割り当てられた「ID」を渡す必要がある。

# そのまま書いても動かない

たとえば \#example チャンネルの情報を得たい時。
URLの中で *channel=example* を指定しても動かない。

`https://slack.com/api/channels.history?token=yyyyyy&channel=example`

次のように「チャンネルID」を指定する必要がある動く。 ( *channel=C065DFECX*  の部分 )

`https://slack.com/api/channels.history?token=yyyyyy&channel=C065DFECX`

## 方法1. チャンネル一覧からコピー

チャンネルを選んで 右クリック→コピー

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/1226bdec-59c8-32da-4018-b201e24ab1e9.png)

こんなURLがコピーされる

https://yuma-inaura.slack.com/messages/C57PALS7M

末尾の部分 **C57PALS7M** がチャンネルID

# 方法2. Slack API の Tester を使う

* 事前にログインとトークンの作成が必要

https://api.slack.com/methods/channels.list/test

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/bd2e4c40-66ab-81f7-7740-3dff67bd4124.png)

JSONでチャンネル一覧が取得できる。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/8852ec03-6b41-579e-7511-9b33f0a9f418.png)

この中の `"name": "example"` の部分がチャンネル名なので、
対応した `"id": "xxxxxxxxx"` の部分を使えば良い。

```json
        {
            "id": "xxxxxxxxx",
            "name": "example",
            "is_channel": true,
            "created": 1448847829,
            "creator": "yyyyyyyyy",
            "is_archived": false,
            "is_general": false,
            "is_member": true,
            "members": [
                "zzzzzzzzz"
            ],
```

`https://slack.com/api/channels.history?token=yyyyyy&channel=xxxxxxxxx`

## 備考

[旧アカウントの記事より移動](https://qiita.com/Yinaura/items/bd28c7b9ef614696fb7e)

いいね数と閲覧数の記録

<details>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/89618/34a08bdb-4add-28d2-39fa-ef87e2600410.png)
</details>








<!-- Update From Qiita API -->

# チャットメンバー募集


何か質問、悩み事、相談などあればLINEオープンチャットもご利用ください。

https://line.me/ti/g2/eEPltQ6Tzh3pYAZV8JXKZqc7PJ6L0rpm573dcQ





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
3D Object Tracking 「Augmented Reality」

以前の2つの記事に僕たちがAR技術を使って2Dデサインをキャプチャして3D Objectや動画を変換することですね。今回は2Dデサインからをキャプチャじゃないくって、もっと次のレベルを試したいとおもうています。何かというか、AR技術を使って3D Objectからキャプチャして別の3D Objectを追加するとか変換することです。結構3D Object Tracking技術が自動車や家具ビジネスでよく使いますよ！
下の写真をご覧ください。
![111.jpg](https://qiita-image-store.s3.amazonaws.com/0/286745/63249898-a3fe-216e-0411-50c5e7720baf.jpeg)
```Source : https://www.youtube.com/watch?v=JMxlLfLaT3Q```


僕は自分の車が持っていないから、今日小さいアスナ(SAO)のFigureを使います（僕はSAOアニメが好きだから、笑）で開発したプロトタイプを皆さんに共有したいと思います,
下の写真をご覧ください。
![11111.jpg](https://qiita-image-store.s3.amazonaws.com/0/286745/687f7c18-76b7-865c-e2a8-7f15081da306.jpeg)

もっと詳しく見たら、その３Ｄ　Ｏｂｊｅｃｔの周りでたくさんdot(点)があります、そのdotは 「Point Tracker」と言います。AR技術はアスナFigure3D のPoint Tracker (X-Axis, Y-Axis)を全部キャプチャして「Frame」になります。

さっき僕が言った通りキャプチャした後3D Objectは別の３Ｄ Objectを追加するとか変換することができます。で例えば僕はアスナ 3D Object から  ユイちゃん (アスナの娘)変換したいです。最初はキャプチャした後3D ObjectをVuforia Developerデータベースを入れて、後でそのデータベースはUnityにインポートします。
![2222.png](https://qiita-image-store.s3.amazonaws.com/0/286745/321b1df0-d66d-caef-a94b-371d137675ce.png)

次ユイちゃんの3D Objectを準備して、ユイちゃんの3D Objectはインポートしたところで入れる。今回も勉強するのために僕は取り扱うインターネットから同じソースを使えます。
![Screenshot_4.png](https://qiita-image-store.s3.amazonaws.com/0/286745/b0484412-2764-e6f8-0ea5-deeb0534eab5.png)
```Source : https://www.models-resource.com```

で最後ウェブカメラを開きて、アスナ3D Objectをキャプチャしましょう！
![Screenshot_20180924-214921.png](https://qiita-image-store.s3.amazonaws.com/0/286745/d346daff-b785-dadd-1357-b35335adc55b.png)

AR技術はアスナの3D Objectをキャプチャして、でキャプチャした情報（Point Tracker）同じかどうかをインポートしたデータベースにチェックします。正しいだったらユイちゃんの3D Objectを表示されます。

じやまたね
面積比から円周率を求める。pythonで実装。

半径１の円に外接する正方形の一辺の長さは2です。
半径１の円の面積は$ \pi $,一辺の長さが2の正方形の面積は4なので、この正方形から内接する円を取り除いた図形の面積は$4-\pi$です。

つまり、この正方形内にランダムに点を十分な数、打っていったときに、円の外にある点と円の内側にある点の数の比は$4-\pi:\pi$であるはずです。円の外側の点の数を$\alpha$,内側の点の数を$\beta$としたとき、円周率$ \pi $は、

```math
\pi = \frac{4\beta}{\alpha+\beta}
```

とかけます。この事実から、円周率$ \pi $を求めてみました。

```python:pi.py
import random
import math
import numpy as np
import matplotlib.pyplot as plt

if __name__ == "__main__":

	number_of_trial = 1000
	history = np.zeros(number_of_trial)
	difference = np.zeros(number_of_trial)

	alpha = 0.0
	beta = 0.0

	for cnt in range(0,number_of_trial):

		xp = random.uniform(-1.0,1.0)
		yp = random.uniform(-1.0,1.0)

		if xp*xp+yp*yp > 1.0:
			alpha = alpha + 1.0

		else:
			beta = beta + 1.0

		history[cnt] = 4.0/(beta+alpha)*beta
		difference[cnt] = abs(math.pi-history[cnt])

	plt.hlines([math.pi], 0, number_of_trial, "red", linestyles='dashed')
	plt.xlim([0,number_of_trial])
	plt.plot(history)
	plt.show()

	plt.plot(difference,color='#4daf4a')
	plt.xlim([0,number_of_trial])
	plt.ylim([0,0.5])
	plt.show()
```
横軸がプロットした点の数。縦軸が計算によって求められた円周率$ \pi $。赤い線が本物の円周率。
![Figure_1.png](https://qiita-image-store.s3.amazonaws.com/0/139546/8ef5f178-64f0-70c7-38c3-5ddbbd75d9d8.png)

本物の円周率から計算によって求められた円周率の差の絶対値をプロットしたもの。
![Figure_2.png](https://qiita-image-store.s3.amazonaws.com/0/139546/84957409-491e-2f20-807d-e9ac4623467d.png)

う～ん、1000回程度じゃあんまりよい値はでないですね。
python import関連のメモ

python 3を対象

### 用語

- module: import される対象(fileのようなもの)
- package: 中に階層構造をもつmodule(difのようなもの)
> \_\_path\_\_ 属性をもってるmoduleはpackageと呼ばれる

- \_\_name\_\_: importするときにmoduleをユニークに識別するのに利用. 完全修飾名で記述 aa.bb.cc 
- \_\_package\_\_: sub moduleなら親のpackage名, top levelのmoduleは空の文字列. 値は文字列

注意：全てのpackageはmoduleだが、全てのmoduleはpackageとは限らない(中に構造がないmoduleもある)

### 検索順序

1. sys.modules:すでにimportされたmodule
2. 組み込みmodule
3. freezeツールで処理されたmodule
4. import pathを起点にしてmoduleの検索

### importの種類

- explicit 相対import (implicit相対importはpython3では廃止)

> from .package import module: current

> from ..package import module: parent

> from ...package import module 

- 絶対 import

> import aaa: sya.pathに存在する必要がある(相対なら from . import aaa)

### explicit 相対importの注意点

1. __package__属性がNoneかつ__name__属性が__main__のとき、相対importは使えない (python xxx.pyを実行時 xxx.py中では相対importは使えない)
2. working dirを通過する相対importは使えない

#### 回避方法

1.について
python aaa/bbb.pyで実行
python -m aaa.bbbで実行

-m option: sys.path から指定されたモジュール名のモジュールを探し、その内容を __main__ モジュールとして実行します。

2.について
working dirをより親にする(もしはsys.pathに追加して)working dirを相対 importが通過しないようにする

[http://d.hatena.ne.jp/chlere/20110618/1308369842]

結局 sys.pathや環境変数PYTHONPATHを使うことになるので絶対importしてsetup.pyを書いてinstallすること推奨
【紹介：GCP Ping】GCPのリージョン毎のレイテンシを知れるサイト

# お題
表題の通り。たまたま職場で知ったので紹介。

# 実践
下記にアクセスすると、GCPの各リージョンのレイテンシが表示されていく。
http://www.gcping.com/

先ほど試したところ、下記の通りとなった。
「東京リージョン」と「フィンランドリージョン」とでは１０倍の開きが。

| リージョン | レイテンシ |
|:--|:--|
| Tokyo ( asia-northeast1 ) | 22ms |
| Global HTTP Load Balancer ( global ) | 26ms |
| Taiwan ( asia-east1 ) | 54ms |
| Singapore ( asia-southeast1 ) | 86ms |
| Sydney ( australia-southeast1 ) | 125ms |
| Oregon, USA ( us-west1 ) | 126ms |
　　　　　　　**・**
　　　　　　　**・**
　　　　　　　**・**

| リージョン | レイテンシ |
|:--|:--|
| London, UK ( europe-west2 ) | 249ms |
| Netherlands ( europe-west4 ) | 257ms |
| Belgium ( europe-west1 ) | 260ms |
| Frankfurt, Germany ( europe-west3 ) | 263ms |
| São Paulo ( southamerica-east1 ) | 286ms |
| Hamina, Finland ( europe-north1 ) | 291ms |

# まとめ
見た通りだけど。
GCP（AWSの場合もそうかな）で例えばインスタンス（GCE）立てる時、何も考えなければ、立ち上げるシステムがどこからアクセスされるか（業種によると思うけど国内からが多いのかな）で、東京リージョンにしておくことが多い気がする。
（さすがに、何も考えず、あえてフィンランドを選ぶことはないと思う。）
レイテンシー的には正解。ただ、コスト（課金）的には実は東京リージョンは他のリージョンに比べて高くつく場合があるので、レイテンシーがさほど重要でない場合は、コスト面で他のリージョンを選ぶべきということもあるみたい。
気が向いたら、GCP内の価格表をリージョン別に一覧化したものでも作ろうか。（サービス毎のは見れると思うけど主要サービスを一覧化というのは無い気がする）
WindowsにBashを導入して人権を回復する

# はじめに
事務作業をする上でWindowsが最強のOSであることは誰もが認めるところだろう。(ExcelもWordもAccessも動くのだから！)

でも開発マシンとしては正直ちょっと使いにくいところがあったりする。例えばRubyをインストールする場合、Macなら次のコマンド一発で完了する。

```bash:
$ brew install ruby
```

一方Windowsの場合は、

- 公式サイトから.exeファイルをダウンロード
- ダウンロードしたインストーラを起動
- 「次へ」ボタンをポチポチする

という作業が発生する。そして残念ながらこの作業の自動化は難しい。

やりにくいのは環境構築だけじゃない。開発中や運用中においてもWindowsはその使いにくさを発揮する。その主な原因がシェル環境の汚さだ。コマンドプロンプトの~~クソみたいな~~構文は使いにくいし、わざわざPowerShellを覚えるくらいならCigwinを入れてシェルスクリプトを書いた方がサーバーとクライアントを統一できるので学習コストが安い。

だがそんな環境も、Windows Subsystem for Linux(旧Bash on Windows)の登場によって一変した。
普段はWindowsを使いながら、必要な時だけUbuntuを使うという選択肢が生まれた。実に素晴らしい。

# Windows Subsystem for Linuxの導入方法

## Windows Subsystem for Linuxを有効化する

1. "プログラムのアンインストールまたは変更"の画面を開く
![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/150087/b6fc4999-ceba-7709-0737-d726bc639240.jpeg)

2. "Windowsの機能の有効化または無効化"を押す
![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/150087/d8140325-a35e-b1ba-9d56-e57ca4eaf903.jpeg)

3. "Windows Subsystem for Linux"にチェックをつける
![WS000004.JPG](https://qiita-image-store.s3.amazonaws.com/0/150087/d7511855-cf6e-3164-53d9-d37536523f95.jpeg)

4. PCを再起動する

## 好きなディストリビューションをインストールする

1. Microsoft Storeを起動する
2. 好きなディストリビューションを選択する
3. インストールしたディストリビューションを起動する

2018年9月28日の時点では「Ubuntu」「openSUSE」「SUSE Linux」「Debian」「Kali Linux」が用意されている。今回は代表的なデスクトップLinuxであるUbuntuを選択した。

インストールしたディストリビューションを起動すると、次のような画面になりユーザーとパスワードの設定が求められる。

```bash:
Installing, this may take a few minutes...
Please create a default UNIX user account. The username does not need to match your Windows username.
For more information visit: https://aka.ms/wslusers
Enter new UNIX username:
```

これでWindows Subsystem for Linuxの導入が完了する。


# やっておくと便利なこと

## Windows側のよく使うフォルダにシンボリックリンクする
上記で導入したLinuxからWindows側のファイルを覗くためには、/mnt以下のパスを参照する必要がある。

だからデスクトップを参照したい場合は"/mnt/c/Users/(user-name)/Desktop/"と打ち込まなければならない。非常に面倒なので、シンボリックリンクしてしまうのがよい。

```bash:
$ ln -s /mnt/c/Users/Desktop ~/Desktop
```

ただしWindows側とのやり取りには注意が必要だ。

WindowsとLinuxではファイルシステムが異なる。そのためLinux側からWindows側を見ると全ファイルが「所有：管理者ユーザー、権限777」という状態になっている。ガバガバだ。

そういう訳なので(SSH鍵等の)権限設定が重要なファイルはLinux側に取り込んでおく必要がある。
angular + firebase逆引きサンプル集

## 概要
https://github.com/angular/angularfire
@angular/fireを試したメモを記載します。
データベースはfirestoreを使う想定です。

## 初期設定
https://github.com/angular/angularfire2/blob/master/docs/install-and-setup.md
正直、公式通りにやるのが一番だと思うのでリンクを張るだけにしておきます。
認証情報はfirebaseコンソールの「アプリを追加」を行うと確認できるようになります。

## Googleアカウントでログインさせたい
```ts
  constructor(public auth: AngularFireAuth) {}

  login() {
    this.auth.signInWithPopup(new auth.GoogleAuthProvider());
  }

  logout() {
    this.auth.signOut();
  }
```

Google認証を簡単に実装することができます。
firebaseコンソールでGoogle認証を有効にする必要があります。

## collectionを取得したい

```ts
  constructor(private afs: AngularFirestore): {
    this.items = afs.collection<Item>('items').valueChanges();
  }
```

collectionとvalueChangesを使います。
返り値はObservableなのでasync pipeなどと組み合わせる必要があります。

## documentを取得したい

```ts
  constructor(private afs: AngularFirestore): {
    this.item = afs.doc<Item>('items/1').valueChanges();
  }
```

docを使うところ以外はだいたいcollectionと同じです。

## documentを作成したい

```ts
  constructor(private afs: AngularFirestore): {
    const shirtsCollection = afs.collection<Item>('tshirts');
    shirtsCollection.add({ name: 'item', price: 10 });
  }
```

addでdocumentを作成した場合、idは自動生成されます。

## idを指定してdocumentを作成したい

```ts
  constructor(private afs: AngularFirestore) {
    this.itemDoc = afs.doc<Item>('items/1');
  }

  create(item: Item) {
    this.itemDoc.set(item);
  }
```

setを使うとidを指定してdocumentを作成することができます。
すでにデータが存在するidの場合はdocumentが上書きされるので注意が必要です。

## documentを更新したい

```ts
  constructor(private afs: AngularFirestore) {
    this.itemDoc = afs.doc<Item>('items/1');
  }

  update(item: Item) {
    this.itemDoc.update(item);
  }
```

updateを使うと上書きではなく、指定したfieldだけを更新をすることができます。

## documentを削除したい

```ts
  constructor(private afs: AngularFirestore) {
    this.itemDoc = afs.doc<Item>('items/1');
  }

  delete() {
    this.itemDoc.delete();
  }
```

deleteでdocumentを削除できます。


## fieldの値で絞り込みたい

```ts
afs.collection('items', ref => ref.where('size', '==', 'large'))
```

クエリはコールバックで渡す必要があります。

## fieldの値で並び替えたい

```ts
afs.collection('items', ref => ref.orderBy('country', 'desc'))
```

だいたいwhereと同じです。

## 本人だけ見れるように制限したい

```
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{user} {
      allow read, write: if request.auth != null && request.auth.uid == user;
    }
  }
}
```

専用のsyntaxでfirestore.rulesを記述します。
client側のクエリがrulesの範囲内でないとパーミッションエラーが発生します。

## 作成日時を保存したい

```ts
import { firestore } from "firebase/app";

firestore.FieldValue.serverTimestamp();
```

いろいろやり方はあると思いますが、firebaseが提供している方法を紹介しておきます。

## collectionを取得したときにidも含めたい

```ts
this.items = afs
  .collection('items')
  .valueChanges({ idField: "id" });
```

valueChangesはデフォルトだとdocumentのidを含みませんが、idFieldを指定することでidも返すことができるようになります。
新しいExcelの一番の変更点は「スピル」？

新しいExcelの性能についてのリリースがあり、ネットでは、VLOOKUP関数が高速になった、AI搭載されたなどのトピックで賑わっています。
でも、実は、表計算の従来の概念を覆すかもしれない、「スピル」という考え方が導入されています。
これはもしかしたら今回のアップデートの一番のインパクトかもしれません。
もしかしたらVBAで作成したプログラムにも影響が出るかもしれません。
そこで、このスピルという新機能について、OfficeInsiderのExcelでいろいろ試してみましたので、その結果を書きます。
# 従来のExcel
今までのExcelでは、いくつかのセルや値を組み合わせた計算式の結果は、1つのセルにしか出ませんでした。
つまり、多入力、単出力という、昔からのコンピュータの原則に沿っていました。
# スピル
スピルとは、簡単に言うと、多入力、多出力です。
ひとつの計算式で、複数のセル範囲に出力できます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/634da6bd-5d9c-2503-49e9-2772c4326fce.png)
これは、新しいExcelで、はじめにA1からB3の範囲に値が入っている状態で、セルD1に「=A1:B3」という計算式を入力しただけのものです。
お気づきの通り、セルD1からE3までにも値が入っています。
これをスピルと呼び、私としては新しいExcelの一番の変更点と考えています。
# 様々なスピルの例
スピルの計算式の形態は様々です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/16e193ea-cab0-1037-0558-93d304292eb9.png)
このようにすべての値に10をかけることもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/663c419d-a6a5-2c28-ce79-be7d90a81624.png)
このように複数列のものに１列の範囲をかけることもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/f32b3f0f-f8ab-dd73-8b94-e8d96811f16c.png)
このように配列をかけることもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/e3768a36-c4ef-557f-b1e3-45b694cf2118.png)
このように外側に関数をつけることもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/565d1252-61da-00bc-f479-08fcceaf2899.png)
このようなVLOOKUP関数の使いかたもできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/b5e33724-4c26-d52e-70d5-1df9d0956546.png)

今までは絶対参照、相対参照、複合参照を組み合わせなければならなかった表も、全く苦労せず出せます。
#スピルの動作
![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/3aea8f28-6bf3-c5d8-eb55-138ca270c720.png)
スピルされたデータに何か書き込まれると計算式を入力したセルに#SPILL!というエラーが発生し、他のデータは消えます。
しかし、書き込んでしまったデータを消せば、スピルは復活します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/3de44b85-dd2e-76c7-72f1-20776448fb73.png)
スピルのデータは、計算式が入力されているセルの番地に#がつくだけでスピル範囲全体を表すので、このようなこともできます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/25332b62-750e-aef5-f09c-e4c1a4aa252f.png)
範囲を出力するため、単独では使えなかったOFFSET関数も単独で使えます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/afddc575-a7e5-6546-df3b-c5a0efca0eb0.png)
INDIRECT関数も同様です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/247287/625ae927-243e-00a2-a71a-acb01b02e893.png)
このように関数の中に関数を入れてスピルすることもできます。
#まとめ
新しいExcelの概念、スピルについて例を挙げて解説しました。
これがいいものなのかどうなのかは現時点で判断できませんが、数式を作成した後にコピーしなくて済むようになったことで、ほんの少しですが、作業時間の短縮にはなっています。
基本情報処理のExcel問題どうなるんだろうかとか、心配もありますが、それよりも従来のExcelシートに影響があるかもしれません。
基本的に範囲で作成した計算式はエラーになっているはずですので、そのようなエラーが回避されていれば問題はないと思います。
もしも、どこかに#SPILL!エラーや、一部#CALCエラーも出るようですので、そのような場合は正常化していきましょう。
もちろんですが、最新版のExcel以外ではスピルはできないので、古いバージョンのExcelで使う場合はスピルを使わないようにしましょう。
と言っても、マイクロソフトさま的にはスピル推奨のようです。従来、スピルと同じような計算式として、配列数式がありましたが、配列数式は非推奨となりました。
新関数としてスピルを使った関数も用意されていますので、あるものは有効に活用していきたいと思います。
WLinux でいろいろやる

Windows Subsystem for Linux 対応ディストリの WLinux が出たとのことで以下試す（順次追加）。

* WLinuxインストール（割引1000円）
* X410インストール
* GUI app 起動
* Token2Shellインストール
* Docker 導入
* Docker Container から GUI app （xfce4 動かす）

WLinux,X410,Token2ShellはそれぞれWindowsStoreからインストール。


# Docker

# 参考

* https://github.com/WhitewaterFoundry/WLinux
* https://token2shell.com/howto/x410/
* https://docs.docker.com/install/linux/docker-ce/debian/
PHP x Markdown or asciidocでテスト仕様書を作って幸せになりたい

# Excelテスト仕様書がつらい
重い。管理が面倒。A1セルにフォーカス当てる？全ブック？なんで途中から連番が手入力なの。。。

# Markdownじゃ対応しきれない
設計書はこれでいいんだけど。。。テスト結果の集計ができない。。。

# データと文書を分割しよう
Markdownで対応できないのはテスト結果というデータを持つから。
なら、これをjsonとかで別に持ってやればいい。

# PHP x Markdown
PHPって別にhtmlに限らずテキスト形式ファイルに出力できる。
テスト項目&結果データを渡してPHPで記述してやればいい。

# やってみた
単純に配列データを表にするだけ。
PHP以外はそのまま出力されるからMarkdownをそのまま書ける。

ディレクトリ構造

```
project
 |
 ├─build
 │  └─test.md
 │
 ├─resources
 │  ├─data
 │  │  └─data.json
 │  │
 │  └─template
 │     └─template.php
 │
 └─src
    └─compile.php
```

```data.json
{
  "contents": [
    {
      "key": "key1",
      "value": "value1",
      "result":true
    },...
  ]
}
```

```template.php
# Parkdown

## Markdown

### table
Percentage :
<?php
class ResultSum
{
    static $sum;

    static function summary($content){
        self::$sum += $content["result"] ? 1 : 0;
    }
}

array_walk($contents, "ResultSum::summary");
echo ResultSum::$sum . "/" . count($contents) . "\n";
?>

|index | key | value | result |
|:---|:---|:---| :---: |
<?php

foreach ($contents as $index => $content) {
    $result = $content["result"] ? "○" : "×";
    echo "|No." . ($index + 1) . "|" . $content["key"] . "|" . $content["value"] . "|" . $result . "|\n";
}
```

```compile.php
<?php

/**
 * 出力先ディレクトリがなければ作る
 * @param $paths
 */
function make_dir($paths)
{
    if (count($paths) > 0) {
        $dir = implode("/", $paths);
        is_dir($dir) or mkdir($dir, 0777, true);
    }
}

/**
 * テンプレートにデータを渡してテキストファイルを作成する。
 * @param $target_resource
 * @param $output_name
 */
function output_file($target_resource, $output_name)
{
    ob_start();
    $contents = json_decode(file_get_contents($target_resource), true)["contents"];

    include("../resources/template/template.php");

    $full_file_name = "../build/" . $output_name;
    $paths = explode("/", $full_file_name);
    array_pop($paths);
    make_dir($paths);
    file_put_contents($full_file_name, ob_get_contents());

    ob_end_clean();
}

output_file("../resources/data/data.json", "test.md");
```

complie.phpを実行すればbuildディレクトリにtest.mdが出力される。

```test.md
# Parkdown

## Markdown

### table
Percentage :
4/6

|index | key | value | result |
|:---|:---|:---| :---: |
|No.1|key1|value1|○|
|No.2|key2|value2|○|
|No.3|key3|value3|○|
|No.4|key4|value4|×|
|No.5|key5|value5|○|
|No.6|key6|value6|×|

```
ファイル監視すれば、変更を即時反映できる。
[ソースコード](https://github.com/Keyhoh/Parkdown)

# メリット
* テスト仕様書の体裁を統一できる。
* 体裁の修正がテンプレートファイル分で済む。
* phpブロックを畳めばMarkdownと同じくらいの可読性
* 別ファイルへのリンクが貼れる
* 学習コストが低い（PHPを本気でやるわけではないので）

# 課題
まだテスト項目・結果データを新規入力・更新するには、データファイルを直接編集しなければいけない状態。
[typora](https://typora.io/)のように出力結果を編集することで元ファイルを更新できるようにしたい。
VSCodeでvue-cliで作成したプロジェクトのESLintを適用する際に.vueファイルが適用されない問題の対処法

## eslintが反映されない
vue-cliいいですよね。コマンド一つで環境を整えてくれるのはありがたいです！
vue-cliが生成するファイルの中にESLintの設定ファイルがあるのですが、VSCodeの拡張を入れるだけでは反映されず、ちょっと設定をいじる必要があったのでシェア。

使用した拡張は以下
![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/9e8f3d04-3871-0d55-f210-88680e0c0da7.png)

## 設定方法
上記の拡張インストール後に
ファイル→基本設定→設定
としてeslintを検索します。デフォルトではユーザ設定を変更するモードになっているので、忘れずに「ワークスペースの設定」タブを選択して、今回の影響範囲をプロジェクトだけに抑えましょう（設定ファイルはプロジェクト固有なので）

![image.png](https://qiita-image-store.s3.amazonaws.com/0/201242/cbd5d65a-e309-c05d-a5f0-44103c06ce78.png)

いくつかの設定はsettings.jsonを直接いじる必要があるので、以下のように記述します

```json:setting.json
{
  "eslint.options": {
    "configFile": ".eslintrc.js"
  },
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    "vue"
  ]
}
```

特に`"eslint.validate"`に`vue`を追加するのを忘れがちなので気を付けましょう！

これで動作すると思います。設定すれば自動で修正する機能もあるのでお好みでカスタマイズしてみてください！
【iOS】MVVMについて

#記事を移動しました。
https://zenn.dev/dd_sho/articles/ec6545ad371137
今後は上記の記事で更新します。（2021/10/03）

MVVMについて一からいろいろ調べて自分なりのあるべき姿が
定まってきたので記事としてまとめます。
RxSwiftの要素はできるだけ排除して、純粋にMVVMについての考察をまとめました。
**※ただし実装にはRxSwiftの利用を前提としています。**

## 前提
この記事では以下の考え方で話を進めます。

1. ビジネスロジックは **Model** で実装する
2. データバインディングには **RxSwift** を利用する
3. 可能な限り１クラス１責務にする

1.について
　MVVMに関する記事を見ているとビジネスロジックをViewModelで実装するか、Modelで実装するか
の２パターンに分かれています。ViewModelで状態を管理しているからビジネスロジックもViewModel
で実装した方が分かりやすい、という意見はよく分かるのですがViewModelの元々の役割を考えると
Modelで実装した方がいいのではと思いました。

2.について
　多くのケースでRxSwiftを採用していることに倣い、RxSwiftを採用します。
　RxSwift便利！！

3.について
　再利用性を考えると１クラス１責務となるのが理想的だと考えています。

## MVVMの構成要素
### Model
- ビジネスロジック（通信処理やDB操作など）
- データ型の定義

### View
ViewModelのデータを、データバインディングで自動的に描画する

### ViewModel
- ViewとModel間の伝達
- Viewのための状態保持

## MVVMの処理の流れ
下図のようなイメージです。

![MVVMイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/139470/4c6c65f9-e2f8-dbdb-1ccb-84f94e80f6ff.png)

上段の左から右への処理は
**ViewはViewModelを参照し、ViewModelはModelを参照することで進んでいき**
下段の右から左への処理は
**ModelからViewModelに通知し、ViewModelからViewに通知することで進みます**
（なんでViewModel→Viewの場合だけを指してDataBindingって言んだろ。）

## ViewModelの構成要素
ViewModelの役割やどう実装するか非常に悩みましたが、にわかながら現状以下のように自分の中でまとまってます。

![VMの構成要素.png](https://qiita-image-store.s3.amazonaws.com/0/139470/092b0899-9a42-559e-7806-63673a8080fe.png)

皆さんはViewModelをどのように実装されているのでしょうか。
**是非コメントお願いします！**

検索バーに入力した文字列でGitHubのレポジトリを検索して一覧表示するサンプルを作ってみました。
ViewModelはこんな感じに実装しました。

```swift:ViewModel.swift

import Foundation
import RxSwift
import RxCocoa

final class RepositoryViewModel {
    
    struct Input {
        // 監視対象（トリガー）
        var repositoryName: Observable<String>
    }
    
    struct Output {
        var rx_repositories: Driver<[RepositoryInfo]>
    }
    
    // MARK: - Properties
    
    // Viewから受け取るトリガー
    private var _input: RepositoryViewModel.Input!
    // Viewにデータをバインドする
    private var _output: RepositoryViewModel.Output!
    // GitHub APIからデータを取得するModel
    private let repositoryModel = RepositoryModel()
    
    // 初期化
    init(trigger: RepositoryViewModel.Input) {
        _input = trigger
        _output = RepositoryViewModel
            .Output.init(rx_repositories: createOutput())
    }
    
    func output() -> RepositoryViewModel.Output {
        return _output
    }
}

extension RepositoryViewModel {
    
    // InputからModel経由でOutputを生成する
    private func createOutput() -> Driver<[RepositoryInfo]> {
        
        return repositoryModel.rx_get(from: _input.repositoryName)
    }
}

```
## プロジェクトにおけるM-V-VMの参照関係
前提の3.「可能な限り１クラス１責務にする」を考えると以下のような関係が良いのではないかと考えます。

![M-V-VMの参照関係.png](https://qiita-image-store.s3.amazonaws.com/0/139470/7f5efd9b-8239-3428-b4c7-96b58d313696.png)

**View : ViewModel = 1 : 1 (間接的に 1 : n はあり得る)**
**ViewModel : Model = 1 : 1**
**Model : Model = n : n**

## まとめ
ここ２、３日で調べたことを基に考えたことをまとめてみました。
まだ書き足りない所はあるけれど、そこは随時更新していきます。
コードも準備できたらリンク貼りますので、良かったら見てやってください。

**まだまだ不十分な部分もあると思いますので、ご指摘いただけますと非常に助かります。**

以上です。
ずんだの縦読み問題 Java 12 Early-Access 版

__元ネタ:__

- [ずんだの縦読み問題](https://qiita.com/higuyume/items/7d3c03ddbbd6f4ad7aa1)
- [ずんだの縦読み問題 php編](https://qiita.com/tbpgr/items/90abccf8297be0e42f8c)

*** 

他言語ではヒアドキュメントなどと呼ばれる機能がJavaでは長らくサポートされておらず、ソースコード内に複数行にわたる文字列を記述したい場合

- ひたすら`+`で結合する。
- `String::join`を活用する。
- 何かしらの外部ライブラリを使う

などの対応を取る必要があり、コードをわかりづらくする原因になってきました。そういう批判・要望を受けてなのか、Project AmberではRaw String Literalという機能が提案されており、2018-09-28現在、JDK12のEarly-Access版に実装されています。

Early-Accessといっても、試すにあたってはさほど難しい手順はなく、[JDK 12 Early-Access Builds](http://jdk.java.net/12/)に用意されている、プラットフォームごとにビルドされたtar-ballを解凍するだけです。わたしはLinux用のtar-ballを利用しました。

```bash
tar xvf openjdk-12-ea+12_linux-x64_bin.tar.gz
```

すると`jdk-12`というディレクトリができるので、そのディレクトリと同じ階層に以下のような`Main.java`を用意します。

```Main.java
public class Main {
    public static void main(String[] args) {
        var tweet = `
            忙しくてついったいじれない
            さみしい
            つらい
        `;
        tweet.align().lines().map(line -> line.substring(0, 1)).forEach(System.out::println);
    }
}
```

あとは以下の要領でコンパイルし、実行すると、想定通りの結果を得ることができました(´・ω・｀)

```bash
$ ./jdk-12/bin/javac --enable-preview --release 12 Main.java
Note: Main.java uses preview language features.
Note: Recompile with -Xlint:preview for details.
$ ./jdk-12/bin/java --enable-preview Main
忙
さ
つ
```

なお詳細なバージョン情報は以下の通りでした。

```bash
$ ./jdk-12/bin/java --version
openjdk 12-ea 2019-03-19
OpenJDK Runtime Environment 19.3 (build 12-ea+12)
OpenJDK 64-Bit Server VM 19.3 (build 12-ea+12, mixed mode)
```


***

__参考:__

- [JDK 12 Early-Access Builds](http://jdk.java.net/12/)
- [JEP 326: Raw String Literals (Preview)](http://openjdk.java.net/jeps/326)
- [Java11、JavaFX11リリース！Java12EAにはRSLが入った](http://d.hatena.ne.jp/nowokay/20180926)
VisualStudio2017のコメントで画像を使えるようにしてみた

今コメントが文字だけでなくプラグイン導入で画像も使えるとのことなのでさっそく導入してみました。

きっかけとなりました素敵な記事です。
[なぜ我々はいまだに文字列でコメントを書いているのか](https://qiita.com/tkrkt/items/2fc9a9a59ce679aab728)

# VisualStudio2017に導入
今回導入したのは下記のプラグインです。
[Memeful Comments](https://marketplace.visualstudio.com/items?itemName=MariusBancila.memefulcomments)

導入自体はダウンロードしてインストールするだけです。
インストールが終わりましたら一度VisualStudioを再起動してください。

#使い方

```C++:hoge.cpp
/// <summy>
/// 省略
/// </summy>
下記の行を挿入
/// <image url="ファイルのパスかURL" scale="画像のサイズの数値" />
void hoge()
{}
```

これだけで画像をコメントとして表示できてしまいます。
サイズも変えることができるので便利だと思います。

私の環境で試してみた結果が下記です。
![コメント.png](https://qiita-image-store.s3.amazonaws.com/0/252878/ec779a0a-0b67-b92d-79d9-b8f2bb753bed.png)

内積のイメージというのはスルーしてください・・・・

プログラムはやはり文字だと説明しにくい部分がありますので今後は会社にも導入を提案してみたいと思います。
IntelliJ IDEAでGo言語(golang)を始める〜GOPATHの設定など


# 概要

新しくGo言語を始める時、どのような環境で書き始めるかいくつか選択肢があると思いますが、私はIntelliJが好きなのでIntelliJを使います。

Goは静的型付けでIDEとの相性が良く、IntelliJはオススメです。

難点はIDEの設定が必要になるところです。一度わかれば簡単ですが、はじめは苦労するかもしれません。
私の場合、自分が作成した別のファイル（パッケージ？）をインポートしようとした時にエラーが出てしまい、解決に苦労しました。

これから始める人が苦労しないように（そして私が解決方法を忘れないように）、ここに書き残します。

# 環境
* macOS High Sierra
* IntelliJ IDEA 2018.2.4(Ultimate)
* go 1.11

# 手順
## IntelliJインストール
Webからダウンロードしインストールします。詳細は割愛します。

## Go言語インストール
Homebrewはインストール済みとします。

```
$ brew install go
```

## IntelliJ設定
### Goプラグインのインストール
下記のパスから見つけてください。

Preferences -> Plugings -> Install JetBrains plugin -> Go

### 設定
下記のパスから見つけてください。その配下にある、GOROOTとGOPATHを確認していきます。

Preferences -> Languages & Frameworks -> Go

#### GOROOT
初めから設定されているはずです。
私の場合は「Go 1.11(/usr/local/Cellar/go/1.11/libexec)」となっていました。このままでOKです。

#### GOPATH
**重要**： これを設定しないと、自分のプロジェクトのコードのインポートが失敗します。自分のプロジェクトがライブラリの探索パスに含まれない、といったほうが分かりやすいかもしれません。標準ライブラリは読み込めるけど、自分が書いたコードがインポートできない状態になります。

正しい設定かどうかは不明ですが、私はこれで動いた、というやり方を説明します。

まず、「Global GOPATH」を削除します。そして、「Project GOPATH」に自分のプロジェクト（IntelliJのプロジェクト）のパスを設定します。

ex. /Users/your_name/IdeaProjects/your_project_name

まだプロジェクトを作成していない場合は、先に作成してからでもいいでしょう。

このやり方で正しく動作しますが（もう少しだけ手順が続きますが）、一つ問題があります。複数のプロジェクトを扱う場合に、毎回この「Project GOPATH」を書き換える必要がある点です。

いろいろネット上の情報を調べましたが、解決方法が見当たりませんでした。

## プロジェクト構成

```
your_project/
    - src/
        - package1/
            - foo.go
        - package2/
            - bar.go
```

"src"を忘れずに作成しましょう。"your_project"はIntelliJのプロジェクト名です。"src", "package1", "package2"は、IntelliJのUIから「New -> Package」で作成します。

foo.goには`package package1`、bar.goには`package package2`をコードに記述します。（ディレクトリ名に合わせます）

これで、例えばfoo.goから`import package2`が成功し、bar.goの関数などが呼び出せるはずです。


# 備考
## GOPATHとGOROOTが正しく設定されているか確認する

IntelliJのUIからTerminalのタブを開きます。そこで`go env`を実行するとGOPATH、GOROOTを含む情報が表示されます。

Terminalは、私の場合は画面下部のRun, TODOのならびにありましたが、表示されていない人は、IntelliJの初期設定の際に無効にしたせいかもしれません。
「Preferences -> Plugins」から"Terminal"を探して、インストールされていなかったらインストールしましょう。


以上です。
Swiftでデザインパターン プロトタイプパターン

# プロトタイプメソッド

- protocolでcloneメソッドを実装する
- サブクラスでprotocolを継承し、cloneメソッド内で新しくインスタンスを作成し、returnする
- 端的にいえば、クラスに自分のコピーを返却するメソッドを実装すること
- このコピーは別のインスタンスというのが重要（値渡しになる）

# メリット
- クラスは参照渡しになるが、cloneを使えば、値渡しになる
- クラスからインスタンスを１から作るのが大変な場合、時間などのコストがかかりすぎる場合
- クラスは通常参照渡しになるが、cloneを使えば、値渡しすることができる
- 複雑な生成処理を気にしないで良い（例: initに値を渡さなければいけない or 生成の手順などを全く気にしなくて良いので使いやすい

```swift

protocol Comment {
    func clone() -> Comment
    func fetchCommentContent() -> [String]
    func pushCommentContent(txt: String)
}

class ArticleComment {
    private var contents = [String]()
    
    init(contents: [String]) {
        self.contents = contents
    }
}

extension ArticleComment: Comment {
    func clone() -> Comment {
        let vc = ArticleComment(contents: self.contents)
        return vc
    }
    
    func fetchCommentContent() -> [String] {
        return self.contents
    }
    
    func pushCommentContent(txt: String) {
        self.contents.append(txt)
    }
}

let comments = ["Amazon最高", "いや、ヨドバシのほうが最高"]
let oldArticleComment = ArticleComment(contents: comments)

// articleCommentを普通に利用する処理があると仮定

// 他の箇所にArticleCommentを渡したい場合
let newArticleComment = oldArticleComment.clone()
newArticleComment.pushCommentContent(txt: "楽天のほうが良い！")

print(oldArticleComment.fetchCommentContent()) // ["Amazon最高", "いや、ヨドバシのほうが最高"]
print(newArticleComment.fetchCommentContent()) // ["Amazon最高", "いや、ヨドバシのほうが最高", "楽天のほうが良い！"]

// 値渡しなので、newArticleCommentに値を追加しても、oldArticleCommentに影響はない
// 複雑な生成処理を気にしないで良い（例: initに値を渡さなければいけない or 生成の手順などを全く気にしなくて良い
// -> インスタンス化が簡単
```

# 総評

- 理解するのは難しくないパターン
- クラスのインスタンスの使い回しなどで活躍できそう
- 他の人がいっていたが、画像描画系などで線のコピーはよくある機能なので、そういったところでも活躍できそう
- チームでやる場合、他の人も読みやすいし、未来の自分も読みやすくなるというメリットもある
- classは普通に扱うと参照渡しになるが、参照渡しは、複雑になったり障害の元になるなど、危険なため、値渡しになるので安全性は高まると思われた

# 補足
- UIViewControllerの場合は、既にcopyメソッドとmutableCopyメソッドが存在する
- oveerideして使う。overrideしないでcopyメソッドを利用した場合、例外が発生する

```swift

import UIKit

class ViewController: UIViewController {
    
    var txt = ""
    
    func setup(txt: String) {
        self.txt = txt
    }
    
    // https://developer.apple.com/documentation/objectivec/nsobject/1418807-copy
    override func copy() -> Any {
        let vc = ViewController()
        vc.setup(txt: self.txt)
        return vc
    }
    
    // https://developer.apple.com/documentation/objectivec/nsobject/1418978-mutablecopy
    override func mutableCopy() -> Any {
        let vc = ViewController()
        vc.setup(txt: self.txt)
        return vc
    }
    
    func shout() -> String {
        return self.txt
    }
}

let vc = ViewController()
vc.setup(txt: "test1")

let vc2 = vc.mutableCopy() as! ViewController
//let vc2 = vc.copy() as! ViewController

vc2.setup(txt: "test2")

print(vc.shout())
print(vc2.shout())
```
一部のAndroid(ZenFone2Laserで確認)でDateTimeが妙な挙動をする件と対策

#DateTimeとAndroid
時刻表示したければDateTime.Nowで時間取ってくればいいと考えるじゃないですか。
実装するじゃないですか。
……なぜか9時間前の時刻が出力されるじゃないですか。
あちゃー、時刻設定がUTCになってたかと確認するじゃないですか。
あれ？　ちゃんとJSTになってる。

さて、どうするか。
#どうしてこうなってるんだ？
どーもコレ、デバイズ自体がタイムゾーン設定関係なく内部ではローカル時刻＝UTCとして処理してて、表示時に設定に合わせて+9時間してるのかなって気配が。JST設定してるのにJST時刻が取得できないからね……。

#対策
まぁ、今回はラクなものです。
向こうがUTCベースで動いてるからおかしくなるなら、こっちもUTCで取得してから変換してやれば最初から問題は起きないです。はい。

DateTime.UtcNowでUTCを取得して、AddHours(9)。
完成。

……それにしても、流石に妙な挙動をし過ぎでは。
商業アプリはこんな訳分からん動きにどう対応しているのか……。(Yahooの乗り換えアプリは普通にデバイズの表示と同じ時刻を取得していた)
さすがにプロがこんな対症療法みたいな対応してるとは考えにくいしなぁ。
React/Vue/AngularでDOMのonやhrefにJavaScriptのソース文字列を使うのはアリか？

React、Vue、Angularユーザーに質問。

JSXやテンプレートのHTMLにおいて、デフォルト挙動のキャンセルのために、ネイティブのon属性等を仕込むのはいいのでしょうか？ まずは、アンケートにご回答ください。

<blockquote class="twitter-tweet" data-cards="hidden" data-lang="ja"><p lang="ja" dir="ltr">React、Vue、Angularユーザーに質問。<br><br>JSXやテンプレートのHTMLにおいて、デフォルト挙動のキャンセルのために、ネイティブのon属性等を仕込むのはアリ？<br><br>例<br>&lt;a href=&quot;javascript:void(0)&quot;&gt;<br>&lt;a onclick=&quot;return false;&quot;&gt;<br>&lt;body ondragstart=&quot;return false;&quot;&gt;<br>&lt;p oncontextmenu=&quot;return false;&quot;&gt;</p>&mdash; 池田 泰延@Adobe MAX Japan登壇 (@clockmaker) <a href="https://twitter.com/clockmaker/status/1045289130639290369?ref_src=twsrc%5Etfw">2018年9月27日</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> 



## 個人的な意見

ここからは個人的な意見です。先のアンケートで「許容する」と回答した方には厳しい意見に思われるかもしれません。先に謝っておきます。


それぞれのライブラリにはイベントのための記法があります。デフォルト挙動をキャンセルするには、イベントハンドラー内で`event.preventDefault()`をするのが定番だと思います。

Reactの場合

```ReactSample.jsx
<a onClick={handler}>ほげ</a>
```

Vueの場合

```VueSample.vue
<a @click="handler">ほげ</a>
```

Angularの場合

```AngularSample.html
<a (click)="handler($event)">ほげ</a>
```

テンプレート文はライブラリの中の世界で書いているのだから、イベントハンドリングの処理は、ライブラリの中で閉じているべきだと考えています。

それが`onclick`属性を使うと、その部分だけライブラリ管理外の領域を呼び出すことになります。インラインでも、関数呼び出しでも同じです。

```VueSample.vue
<a @click="handler()">ほげ</a>
↓
<a onclick="return false;">ほげ</a>
```

`href`属性にJavaScriptを仕込むのも、同じことです。

```VueSample.vue
<a href="javascript:void(0)">ほげ</a>
```


ライブラリの秩序を崩壊するような気がするのですが、いかがでしょうか？

アンケートの回答を割合を見ると、許容している人が多いことに驚きました。理想的な作り方などどうでもいい、目の前の案件を片付けるために動けばいいという観点だけで作っている人が多いのでしょうか。

※今回はデフォルト挙動のキャンセルのための話に限定しましたが、それ以外の目的でもReact/Vue/Angularの使用範囲内でリアルDOMのイベント属性を使うのは微妙（というかNG）だと考えています。
※とはいえ、ReactもVueもAngularのいずれの公式ドキュメントに非推奨としている記載は見つかりませんでした。はたして公式見解はどうなのでしょう。


## ことの発端

東京五輪のボランティア募集サイトがReactで作られているにもかかわらず、`href="javascript:void(0)"`が頻出する設計となっていました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">オリンピックのボランティア募集サイトが酷いと話題だったので、コードを見てみたら残念品質でした･･･<br><br>・重複したid属性<br>・javascript:void(0)<br>・まともに実装されてないWAI-ARIA<br>　（音声読上も酷い）<br>・body内にstyleタグが頻出<br><br>これらは一例。ちなみにReact製。<a href="https://t.co/jQDNk9r0dO">https://t.co/jQDNk9r0dO</a> <a href="https://t.co/ed6TrpByy1">pic.twitter.com/ed6TrpByy1</a></p>&mdash; 池田 泰延@Adobe MAX Japan登壇 (@clockmaker) <a href="https://twitter.com/clockmaker/status/1045188793685299201?ref_src=twsrc%5Etfw">September 27, 2018</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

Reactの使い方として良いのか悪いのか意見を求めたく、アンケートを実施した次第です。

## ユーザービリティーの観点

話は脱線しますが、`href`属性にJSを書くのは、ユーザーフレンドリーでは邪道と考えています。

```html
<a href="javascript:void(0)">ほげ</a>
```

なぜならば、ブラウザのステータスバーにリンク先が表示されるからです。
国内の多くのウェブサイトで`<a href="javascript:void(0)">`が使われているように感じています。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/2544/96f012f1-9f49-4290-331d-8923a5b9be43.png)

どうでもいいですが、`a`タグに`alt`属性ついてるのもびっくりです･･･。


## 関連記事

- [ReactでWAI\-ARIA対応のタブ型UIを実装する方法 \- ICS MEDIA](https://ics.media/entry/17109)
未再現 iPhoneでposition: fixedが効かない時の原因の一つ

```
<div class="fixed">
  Something
</div>
<div>
  <img style="position: absolute;">
  <img style="position: absolute;">
</div>
```

のように、インライン要素に`position: absolute;`をつけて並べてしまうと、
fixedの要素がなぜか普通にスクロールされてしまいました。
`display: block;`をimgにつけると直りました。
めっちゃ怪しいので要検証です。
Web Share API が Safari で使えるようになったので早速使ってみる

# 概要
昨日 (2018/9/26) リリースされた `Safari Technology Preview Release 66` が `Web Share API` に対応したということで、早速試してみました。

これで `Web Share API` は `Android の Chrome` と `Safari Technology Preview Release 66` で使用できるようになりました。 

下記に本稿のソースコードとデモページを用意しました。
[im36-123/webShareApi | GitHub](https://github.com/im36-123/webShareApi)
[デモページ](https://im36-123.github.io/webShareApi/)

[^1]: [Release Notes - Safari Technology Preview - Safari - Apple Developer](https://developer.apple.com/safari/technology-preview/release-notes/)

# 実装したコード
`<button>` をクリックすると `navigator.share()` メソッドを実行します。

```html
<!DOCTYPE html>
<html lang='ja'>
<head>
    <title>Web Share API</title>
</head>
<body>
    <button>Share</button>
    <script>
        const button = document.querySelector('button')
        button.addEventListener('click', (e) => {
            navigator.share({
                url: '',
                title: document.title,
                text: 'Web Share API を使ってみる'
            })
        })
    </script>
</body>
</html>
``` 

# 実行結果

## Safari の場合
Safari では下記のように表示されます。
![Sep-27-2018 23-27-43.gif](https://qiita-image-store.s3.amazonaws.com/0/280341/c01429dc-8683-c31c-ded3-37c7020ae1e3.gif)


## Android の Chrome の場合
Android の Chrome では下記のように表示されます。
ネイティブのシェアメニューが表示されます。
![9月-28-2018 16-11-02.gif](https://qiita-image-store.s3.amazonaws.com/0/280341/dc2bba44-bb00-7b35-9f25-d71e887ab40c.gif)


# 参考
[Release Notes - Safari Technology Preview - Safari - Apple Developer](https://developer.apple.com/safari/technology-preview/release-notes/)
[Introducing the Web Share API  |  Web  |  Google Developers](https://developers.google.com/web/updates/2016/09/navigator-share)