OmniAICreator/Qiita-1.07M huggingface dataset:
2rep - Azure DevOps Azure Pipelines docker-compose build編

前回 **[3分でできるAzure DevOps Azure Pipelines編 ~](https://qiita.com/MarcyMarcy/items/c48b6ad5570a4c883c7f)**を書きましたがその延長で、docker-composeのファイルの場合のものをやっていなかったなぁと思いメモ。

```
Azure DevOpsとは
「最新の一連の開発サービスを利用して、よりスマートに計画を立て、より効率的に共同作業を行い、より迅速に公開しましょう。」
(Github + Zenhub + 開発グループウェア + circleci が一つになったような感じです。)

公式サイト引用：https://azure.microsoft.com/ja-jp/services/devops/https://azure.microsoft.com/ja-jp/services/devops/

その中でも、Azure Pipelines(CI/CD)とDockerfileを使い簡単に、ビルドを自動化してみましょう。
（類似するサービスで、circleci codeshipなどがあります。）
```

# 1.前回同様リポジトリにdocker-composeのファイルをアップ
PHP Paravelとなっております。
<img width="1337" alt="スクリーンショット 2018-12-29 3.01.56.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/50eb72ab-c9a2-f576-d006-3b7c2422f4a4.png">

# 2.Pipelinesに移動　New pipelineをクリック

画像の通りに押して進む。
<img width="1338" alt="スクリーンショット 2018-12-29 3.04.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/188065c3-45c5-dfab-7e46-cdfd8c034383.png">

<img width="1336" alt="スクリーンショット 2018-12-29 3.05.12.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/c92eeabf-24ea-1982-02cc-00565eac2324.png">

<img width="1341" alt="スクリーンショット 2018-12-29 3.05.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/4ae95064-f0e5-5149-7d49-8cd99696e67e.png">

<img width="1339" alt="スクリーンショット 2018-12-29 3.05.35.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/7ce97f63-79f3-20ae-2af6-599c7b154d35.png">

# 3.設定ファイル
<img width="1384" alt="スクリーンショット 2018-12-29 3.07.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/6130aca9-17e6-5417-87a7-61b36b668ef5.png">

### Dockerfile単体の場合
```
steps:
- script: docker build -f .docker/golang/Dockerfile -t $(imageName) .
```

### docker-composeの場合
```
- script: |
    docker-compose -f docker-compose.yml --project-directory . -p docs up -d
    docker wait docs_sut_1
    docker-compose -f docker-compose.yml --project-directory . down
```

docker-compose.ymlのファイルが存在する箇所にパスを合わせてください。

### 結果

```
# Docker image
# Build a Docker image to deploy, run, or push to a container registry.
# Add steps that use Docker Compose, tag images, push to a registry, run an image, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/docker

trigger:
- master

pool:
  vmImage: 'Ubuntu-16.04'

variables:
  imageName: 'php-laravel:$(build.buildId)'

steps:
- script: |
    docker-compose -f docker-compose.yml --project-directory . -p docs up -d
    docker wait docs_sut_1
    docker-compose -f docker-compose.yml --project-directory . down
  displayName: 'PHP-Laravel docker build'
```

# 4.いざ実行
<img width="1111" alt="スクリーンショット 2018-12-29 3.11.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/830758e1-3731-6f69-ec0f-f73fce100a2d.png">

<img width="1117" alt="スクリーンショット 2018-12-29 3.14.02.png" src="https://qiita-image-store.s3.amazonaws.com/0/326491/88a54e26-e9a6-9960-3b32-652cf3383a01.png">

無事ビルド完了〜！

> Azure DevOps Azure Pipelines
Pipelinesは10個の無料並列ジョブをサポートされており、
先に使っている人をまたずテストが可能です。
MacでVSCodeがうまくUnityのコードを補完してくれないとき

なんか中途半端に予測が聞かない。VSCodeのOmni Sharpのログを見るとProjectがうまく読めていないことがわかった。

```
 The reference assemblies for framework ".NETFramework,Version=v4.7.1" were not found. To resolve this, 
install the SDK or Targeting Pack for this framework version or retarget your application to a version of the 
framework for which you have the SDK or Targeting Pack installed. Note that assemblies will be resolved from 
the Global Assembly Cache (GAC) and will be used in place of reference assemblies. Therefore your assembly may 
not be correctly targeted for the framework you intend.
```


.Net Coreでは.net 4.5相当のコードを実行することはできないのでMonoを入れる必要がある。

```
brew install mono
```

前に入れた覚えがある人は`brew upgrade mono`をして最新版にしよう。
その上でVSCodeの設定に以下のようなものを足す。

```
  "omnisharp.useGlobalMono": "always",
  "omnisharp.monoPath": "/usr/local/Cellar/mono/5.16.0.220"
```

下の`monoPath`は執筆時点で最新のバージョンを具体的に示したものだが、僕の環境ではPATHに通っていたとしても、このように強制的にMonoのパスを示していない場合は動作をしなかった。
Python - paramikoで Cisco Webex Devices を操作する

[Cisco Systems Japan Advent Calendar 2018](https://qiita.com/advent-calendar/2018/cisco)
をみながら、私のフィールドのビデオ会議関連に何か役立てないかなと徒然書く企画の1回目です。

@radiantmarch さんの [第2回: ネットワーク自動化開発実践 - Python でルータを操作する](https://qiita.com/radiantmarch/items/936b43f32210e4689179) を参考に、Python での Cisco Webex Devices の API である [xAPI](https://developer.cisco.com/site/roomdevices) 操作を SSH 経由で考えてみます。通常、xAPI は HTTP POST で操作可能なので、オススメは REST ですが、社内セキュリティなどで Web サーバを Disable にする必要があり SSH でしか API を叩けないという想定となります。

# Cisco Webex Devices を Python で操作する

[paramiko](http://www.paramiko.org/) をインストールします。[ルータに接続してコマンドを実行する Python コード](https://qiita.com/radiantmarch/items/936b43f32210e4689179#1-paramiko-%E3%82%92%E4%BD%BF%E3%81%86)のうち、 send the command の部分を xAPI の書式に書き換えます。

```Python
# send the command
remote_shell.send("xstatus SystemUnit Software Version\n")
time.sleep(1)
output = remote_shell.recv(65535)
print(output)
```

出力結果はこんな感じでした。例えばこれを定期的にかけて、クラウド登録時にソフトウェアのバージョンアップがあれば知らせる、ということもできそうですね。

```
-------------------- 10.X.X.X  --------------------
b'Welcome to \r\nCisco Codec Release RoomOS 2018-12-06 7513bae968a\r\nSW Release Date: 2018-12-06\r\n*r Login successful\r\nOK\r\n\r\n'
b'xstatus SystemUnit Software Version\r\n*s SystemUnit Software Version: "ce9.7.0.7513bae968a"\r\n** end\r\n\r\nOK\r\n'
```

## Python から自動発信

上記を少し改造して、通話状態をチェックし、通話がなければ自動発信させるスクリプトを考えてみます。

通話状態は Cisco Webex Devices xAPI コマンドでは

```
xstatus Call Status 
```
で取得できます。通話があるときはそのステータス、通話がないときはエラーが返ります。

```
xstatus Call Status 
*r Status (status=Error): 
*r Status Reason: "No match on address expression"
*r Status XPath: "Status/Call/Status"
** end

ERROR
```
強引ですが、**status=Error** が返り値に含まれていたら発信をするようにします。発信するコマンドは

```
xcommand Dial Number:発信先
```
です。

少し間を置きながら、こんな感じの書き方で動作を確認しました。

```Python
# send the command
remote_shell.send("xstatus Call Status\n")
time.sleep(1)
output = remote_shell.recv(65535)
time.sleep(2)
if 'status=Error' in output.decode():
    remote_shell.send("xcommand Dial Number: example@example.com\n")
    time.sleep(2)
    output = remote_shell.recv(65535)
    print(output)
else:
    print(output)
```

出力（通話成功）

```
-------------------- 10.X.X.X  --------------------
b'Cisco Codec Release ce 9.6.0 8ea7f63e365 2018-11-20\r\nSW Release Date: 2018-11-20\r\n*r Login successful\r\nOK\r\n\r\n'
b'xcommand Dial Number: example@example.com\r\n\r\nOK\r\n*r DialResult (status=OK): \r\n*r DialResult CallId: 21\r\n*r DialResult ConferenceId: 16\r\n** end\r\n'
```

出力(失敗)

端末の現状のステータスを出力、ここでは **EarlyMedia** を表示して終わり。

```
-------------------- 10.X.X.X  --------------------
b'Cisco Codec Release ce 9.6.0 8ea7f63e365 2018-11-20\r\nSW Release Date: 2018-11-20\r\n*r Login successful\r\nOK\r\n\r\n'
b'xstatus Call Status\r\n*s Call 22 Status: EarlyMedia\r\n** end\r\n\r\nOK\r\n'
```


# Cisco Webex Devices で netmiko はできるのか？

[netmiko](https://qiita.com/radiantmarch/items/936b43f32210e4689179#2-netmiko-%E3%82%92%E4%BD%BF%E3%81%86) は残念ながら Cisco Webex Devices xAPI に対応していません。
ただ、特権モードや Config モードなどの考え方がないので、単純な応答であれば上記の paramiko で頑張るのがよいかもしれません。

# 謝辞

@radiantmarch さん、素晴らしい投稿ありがとうございました。
Pythonのfromとimportがいつもごっちゃになるので、無理やりこじつけてみた

#はじめに

Pythonでライブラリを使うときに宣言する、
`from`
`import`
がごっちゃにならないようにする、独自の無理やりな覚え方です。

#`from`と`from`を混同してしまう場合の覚え方
`import`にも`from`にも、'm'と'o'のアルファベットが含まれてます。

m →　module
o　→　object

と連想して無理やりこじつけます。

##`import`のみの場合

```python:script.py
import time
```
import の'm'から'module'を連想する。

import <モジュール名>

## from *** import *** の場合

`from`がある場合、`import`はモジュールではなく、オブジェクトのインポートを意味します。
私の場合、ここが混同する原因でした。

from <モジュール名>　import <オブジェクト>

覚え方としては、それぞれのスペルを「後ろ」から読んで、連想してみます。

from →　fro'm'：後ろから読むと、oよりmが先に来るので、モジュール（module）。
import →　imp'o'rt：後ろから読むと、mよりoが先に来るので、オブジェクト（object）。

以上、かなり無理やりですが、ど忘れした時の参考になれば幸いです。

#ちょっと解説
Pythonでは、
ファイルは、**モジュール**（module）、
関数、クラス、変数、サブモジュールなどは、**オブジェクト**（object）、
と言います。

私の場合、ネットで独学が基本だったので、ここがよく分かっていなかったのですが、
`import`も`from`も
すぐ後に続くモジュールをインポートします。

```python:script.py
import os  # モジュール os をインポート
import selenium  # モジュール selenium をインポート
from selenium import webdriver  # モジュール selenium のオブジェクト（サブモジュール） webdriver をインポート 
```
##import
Pythonでは、関数やクラスを書いたファイルのことを**モジュール**と呼びます。
`import <モジュール名>`とすると、モジュールがインポートされます。

```python:test.py
import time
import os

print (type(time))
# <class 'module'>

print (type(os))
# <class 'module'>

print (time)
# <module 'time' (built-in)>

print (os)
# <module 'os' from '/usr/local/Cellar/python/3.7.1/Frameworks/Python.framework/Versions/3.7/lib/python3.7/os.py'>

```

#from
`from <モジュール名> import <オブジェクト名>`を使うと、モジュール内のオブジェクト（関数、変数、クラス、サブのジュールなど）をインポートします。

インポートされるのはオブジェクトのみです。（下の例では、`webdriver`）

```python:test.py
from selenium import webdriver
```
Daily IOS チャレンジ Day1

前々からIOS, Swiftには触れていたのですが、
これといってがっつりと勉強する機会がなかったので、
とあるきっかけで毎日30分ずつ勉強することにしました。

Day1:
　「ボタンをタップで画面遷移」を実装

スタンバイ
Xcode open → create a new xcode project → single view app → next
→add ProductName →　Next

StoryBourdにMainのStoryBourdから遷移するViewControllerを新規作成

画面遷移をするボタンを配置　→　右クリック　→　Triggered Segues　→　actionから遷移先にドラッグ→Present as Popper

最後に実行

![DailyChallenge1.gif](https://qiita-image-store.s3.amazonaws.com/0/260218/4ecc310a-4b30-d394-997d-09511580cbec.gif)
if文を使わないFizzBuzz

## まずは普通のFizzBuzz

```bash:fizzbuzz.sh
#!/bin/sh
for i in {1..100}
do
  if [ $(( ${i} % 3 )) -eq 0 ]; then
    s="Fizz"
  else
    unset s
  fi
  if [ $(( ${i} % 5 )) -eq 0 ]; then
    s=${s}"Buzz"
  fi
  echo ${s-${i}}
done
```
工夫したのは`echo ${s-${i}}`です。この`-`は、左側が定義済みであれば左側の値を使用、未定義であれば右側の値を使用する、というシェル変数独特の記法です。実質的にこの中に判断文が入っているわけですが、見た目はif文を減らすことができます。

## if文を使わないFizzBuzz
そこで思いついたのが、こんなプログラムです。

```bash:fizzbuzz2.sh
#!/bin/sh
for i in `seq 3 3 100`
do
  a[${i}]="Fizz"
done

for i in `seq 5 5 100`
do
  a[${i}]=${a[${i}]}"Buzz"
done

for i in {1..100}
do
  echo ${a[${i}]-${i}}
done
```

一応、if文は使っていません。`-`が実質的に判断文といえばそうですが。
判断文を全く無くすとしたら、最初に配列の中身を全部数字で埋めるんでしょうね。
画像屋は夢想する　「脳の意識　機械の意識　脳神経科学の挑戦」

脳科学関係の書籍を紹介する。

[渡辺正峰　「脳の意識　機械の意識　脳神経科学の挑戦」中公新書
2017年発行](http://www.chuko.co.jp/shinsho/2017/11/102460.html)
![](http://www.chuko.co.jp/book/102460.jpg)


[利根川進　著「私の脳科学講義」](https://www.iwanami.co.jp/book/b268574.html)
![](https://www.iwanami.co.jp//images/book/268574.jpg)


## はじめに
深層学習が近年進展している。そのアイディアの大元は、初期の脳科学ででてきた神経回路網のモデルがヒントになっている。GPUに代表される計算能力の拡大は、1980年代のback propagation を実用的な問題に適用可能にした。しかも、アルゴリズムの改良も大きい。

深層学習の話はいったんおいといて、脳科学の実験の進展が何があるのかが読めるのがこの本だ。


## 私達が、日常見ているものは、「ありのままの外界」ではない。
「私たちが見ているように感じるのは、眼球からの視覚情報をもとに、脳が都合よく解釈し、勝手に創りだした世界だ」
そのことを実感できる例を、この本では紹介している。
両眼視野闘争もその一つだ。

この本には、まさしく両眼視野闘争を経験するページが含まれている。

[両眼視野闘争 - 脳科学辞典 ](https://bsd.neuroinf.jp/wiki/%E4%B8%A1%E7%9C%BC%E8%A6%96%E9%87%8E%E9%97%98%E4%BA%89)


利根川進　著「私の脳科学講義」岩波新書の中でも両眼視野闘争の実験が紹介されている。

図2.5 サルを使った視覚交代実験　p.69　がかかれている。

## 神経伝達の時間差を意識しないのはなぜか
また、人の神経細胞を通じた情報の伝達と知覚処理は、遅延を持っている。複数のセンサ（感覚器）からの到達して知覚されるはずの時間は違っているはずなのに、その時間差を意識していない。

人工システムである監視カメラなどでは、処理の遅延が無視できない。NTSCのアナログの監視カメラの時代より、デジタルの監視カメラでは、撮影と表示の間でさえ遅延が無視できない。デジタルカメラの前で手のひらを左右に振ってみて、どれくらい遅れているのかを見てみるとよい。さらに、ターゲットの検出処理が入ると、検出結果が得られた時には、ターゲットは更に移動してしまっている。

しかし、ヒトを含む生き物の知覚処理は、そのような遅れを意識することなく、移動している物体を手にとることができるものになっている。

その秘密は、どこにあるのか考えてみることです。
自分で考えてみることが大切だと思うので、その答らしい情報はここでは述べないことにします。


## よい実験とは何か
また、２つの本に共通なことは、よい実験とはどういうことかが書かれているということ。

よい実験とは何かを知っていることは大切で、よい実験を知っている研究者の弟子は、よい研究を成し遂げることが多いらしい。
ノーベル賞の受賞者の弟子にノーベル賞受賞者がいたりすることがあるのは、よい実験とは何かを知っていることから出てくるらしい。

[利根川進](https://ja.wikipedia.org/wiki/%E5%88%A9%E6%A0%B9%E5%B7%9D%E9%80%B2)　氏の脳科学への研究は、遺伝子組み換え技術でノックアウトマウスを作り、それを脳の研究に結びつけたという点において、脳科学の進歩を創りだしたものということだ。
VS Codeを快適にするためにしていること

# はじめに
VS Codeを快適に使うためにやってることを紹介したい.順次更新予定.

# サイドバーでの選択時にサイドバーが自動で閉じるようにする

## 動機
サイドバーで何かを選択した時(ファイルとか拡張機能とか)
サイドバーが開きっぱになっているのはうれしくない

## やったこと
サイドバーで何かを選択したのに連動してサイドバーを閉じるようにした

## 用いた拡張機能
multi-command
https://marketplace.visualstudio.com/items?itemName=ryuta46.multi-command

実現するのに用いた拡張機能
これは複数のVS Codeのコマンドを新たに一つのコマンドとして登録してくれる拡張機能.
シンプルな拡張機能だが効果は絶大


## やり方
上記の拡張機能を用いて「サイドバーでの選択」と「サイドバーを閉じる」を行うコマンドを新たにVS Codeに登録する

「サイドバーでの選択」はlist.select,「サイドバーを閉じる」はworkbench.action.toggleSidebarVisibilityという名前のコマンドで行われてるので以下をsetting.jsonに追記する.

```:
"multiCommand.commands": [
        {
            "command": "multiCommand.listSelect_and_closeSidebar",
            "sequence": [
                "list.select"
                ,
                "workbench.action.toggleSidebarVisibility"
            ]
        }
]
```

これで「選択」と「サイドバーを閉じる」を順次実行してくれるコマンドが"multiCommand.listSelect_and_closeSidebar"という名前でVS Codeに登録された(ちなみに自分はsequenceの順番を逆にしている.先にサイドバーが閉じるほうが自然な挙動に思えたからだ.)

あとはこれにショートカットキーを割り付ける

もともとサイドバーでの選択にはenterキーが割り付けられているので,それをctrl+enterに変更し新たに作ったコマンドにenterを割り付ける
具体的には以下をkeybindings.jsonに追記することとなる

```
    {
        "key": "ctrl+enter",
        "command": "list.select",
        "when": "listFocus && !inputFocus"
    },
    {
        "key": "enter",
        "command": "multiCommand.listSelect_and_closeSidebar",
        "when": "listFocus && !inputFocus"
    },
```

これでファイルや拡張機能をenterで選択したとき,自動でサイドバーを閉じてくれる(やった!)
Javascriptアプリの最速ビルドツール Meteor試してみた

#Meteorを使えばJavascriptアプリを最速でビルドできる!
って公式に書いてありました
原文: 「THE FASTEST WAY TO BUILD JAVASCRIPT APPS」

<img width="1427" alt="Screen Shot 2018-12-29 at 1.33.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/94861/0fd7790d-54b6-b6b1-4c6c-9edbe95ba013.png">


# 実際に試してみる
インストールして、ブラウザで表示するまでの[チュートリアル](https://www.meteor.com/tutorials/react/creating-an-app)があるので試してみる。

## Install

```
curl https://install.meteor.com/ | sh
```

## Create Project
	
```
meteor create myapp
```

## Run
さりげなくmongodbが動くのが強いなって思いました

```
cd myapp && meteor

[[[[[ ~//Meteor/myapp ]]]]]     

=> Started proxy.                             
=> Started MongoDB.                           
=> Started your app.                          

=> App running at: http://localhost:3000/
```

##動作確認
[localhost:3000](http://localhost:3000)にアクセスすると下記の画面が表示される。
mongodbはポート3001で動作しているみたい。

<img width="1439" alt="Screen Shot 2018-12-29 at 1.29.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/94861/0c1cb30e-2db7-f08c-a99a-b7cf751fb1aa.png">


#まとめ
- Javascriptのアプリをさくっと作る際に、手軽に動かせることがわかった
- mongodbがデフォルトで起動するため、モック作りたい時とかは重宝するかも
dissolve shaderを読む

#dissolve shader
[dissolve shader - jsdo.it](http://jsdo.it/takumifukasawa/OfdS)
takumifukasawaさんのdissolve shaderを自分なりに調べさせていただいた記事です。


<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">Dissolve 作ってみました。<a href="https://twitter.com/hashtag/webgl?src=hash&amp;ref_src=twsrc%5Etfw">#webgl</a> <a href="https://twitter.com/hashtag/threejs?src=hash&amp;ref_src=twsrc%5Etfw">#threejs</a> <a href="https://t.co/IdVUXazLTG">pic.twitter.com/IdVUXazLTG</a></p>&mdash; yukidoke (@snowdoke) <a href="https://twitter.com/snowdoke/status/1064187235229040640?ref_src=twsrc%5Etfw">2018年11月18日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


```glsl
<script type="text/v-shader" id="v-shader">    
    varying vec2 vUv;
    attribute vec2 uvs;
    void main(void) {
        vUv = uvs;
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
</script>

<script type="text/f-shader" id="f-shader">    
    precision mediump float;  // floatの浮動小数点数の演算精度をすべて中精度で行う
    varying vec2 vUv;  // v-shaderで処理されて渡されるテクスチャ座標
    uniform sampler2D diffuseMap;  // 拡散マップ
    uniform sampler2D heightMap;  // ハイトマップ
    uniform float uTime;  // 経過時間
    uniform float range;  // 範囲
    void main(void) {
        vec4 diffuseColor = texture2D(diffuseMap, vUv);  // 色を取り出す
        vec4 heightColor = texture2D(heightMap, vUv);  // 色を取り出す
        vec4 destColor = diffuseColor;  // 最終的に得られる色
        
        float height = heightColor.r;  // ハイトカラーのred
        
        float rate = mod(uTime / range, 1.);  // modは、x-y*floor(x/y)を返す
        
        if(height < rate) {  // もし、ハイトがレートよりも小さかったら
            discard;  // その画素を画面に描かない
        }
        
        float offset = rate + .04;  // レートを少し早める
        if(height < offset) {  // もし、ハイトがオフセットよりも小さかったら
            vec4 orange = vec4(254. / 255., 99. / 255., 6. / 255., 1.);  // オレンジ色
            vec4 black = vec4(0., 0., 0., .6);  // 黒色
            float step = smoothstep(0., offset - rate, offset - height);  // smoothstepは、エルミート補完を行う
            destColor = mix(black, orange, step);  // mixは、x(1-a)+y*aを返す
        }
        
        gl_FragColor = destColor;
    }
</script>
```
【2018年の総括】QiitaでPython関連10000件記事に付けられたタグの種類と出現回数をSeleniumを使ってスクレイピングで調べてみた

#きっかけ
このQiitaでは、年間数多くの記事が投稿されていますが、2018年は、どのような話題が一番多かったのでしょうか？

ちょっと興味があったので、Python関連記事１つ１つ付けられている「タグ」に注目し、python + seleniumでスクレイピングによるタグ（キーワード）を集計するプログラムを作ってみました。

※ 正確には、2018/12/24現在で過去10,000件のデータを参照しましたので、正確に2018/1/1からのデータではありません。

#使用したプログラムのコードについて
プログラムのコードについては、スクレイピングプログラムの作り方というテーマで動画化して udemyで無料公開していますので、ぜひ御覧ください。
Google Chromeの検証機能で「CSSセレクタ」を参照し、Seleniumで指定する方法などがわかると思います。

[【夢月流】Pythonスクレイピング入門～Webスクレイピングプログラムを素早く作るコツを教えます～](https://www.udemy.com/pythonweb/learn/v4/overview)

#プログラムの内容
基本的に以下のようにSeleniumで画面遷移を行っています。

- [Qiita初期画面(未ログイン状態)](https://qiita.com/)
- 上記状態からログインGoogle連携で、メールアドレスとパスワードを入力）
- [Python記事一覧画面](https://qiita.com/tags/python)

この最後のPython記事一覧画面において、最新投稿分から順次過去投稿分に遡って、１つ１つ付けられているタグの種類と、その出現個数を数えています。

記事一覧は各ページ20記事があり、500ページに渡って調査したので、合計10,000個の記事について調べました。

#その結果は・・・

pythonタグを含めて、合計3661個のタグが付けられていました。
そのうち、出現回数が10未満のものが、3312個となっており、かなりバラツキがあります。

##Pythonタグと一緒に付けられたタグで、出現回数の多いのは？
出現回数の多い上位100タグは下記のとおりでした。
（1位のPythonは、Python記事のみ対象にしたので、タグ出現回数は当然10000回です。）

上位は、機械学習、DeepLearningなどAI関係がやはり多いですよね。

|No|タグ名|出現回数|
|--:|:---|----:|
|1|Python|10000|
|2|Python3|1390|
|3|機械学習|813|
|4|DeepLearning|575|
|5|Django|458|
|6|pandas|416|
|7|TensorFlow|366|
|8|Keras|365|
|9|numpy|318|
|10|matplotlib|289|
|11|Jupyter|267|
|12|RaspberryPi|253|
|13|MachineLearning|249|
|14|AWS|238|
|15|Anaconda|219|
|16|OpenCV|218|
|17|Flask|212|
|18|初心者|208|
|19|自然言語処理|189|
|20|docker|185|
|21|データ分析|173|
|22|scikit-learn|168|
|23|lambda|148|
|24|ディープラーニング|136|
|25|スクレイピング|133|
|26|Chainer|123|
|27|JavaScript|117|
|28|pip|115|
|29|Kaggle|114|
|30|数学|111|
|31|pyenv|105|
|32|Mac|104|
|33|Selenium|103|
|34|Twitter|101|
|35|PyTorch|98|
|36|画像処理|92|
|37|AI|89|
|38|python2.7|84|
|39|Ruby|81|
|40|mecab|78|
|41|Ubuntu|78|
|42|Windows|76|
|43|強化学習|72|
|44|IoT|72|
|45|Slack|72|
|46|ProjectEuler|71|
|47|R|70|
|48|api|68|
|49|Heroku|66|
|50|Pycharm|66|
|51|colaboratory|65|
|52|BeautifulSoup|65|
|53|深層学習|64|
|54|統計学|64|
|55|TwitterAPI|64|
|56|Java|61|
|57|GoogleColaboratory|60|
|58|C++|60|
|59|最適化|59|
|60|Jupyter-notebook|58|
|61|Pipenv|56|
|62|CNN|55|
|63|GoogleCloudPlatform|55|
|64|データサイエンス|54|
|65|scipy|52|
|66|Azure|52|
|67|JSON|52|
|68|Excel|50|
|69|数値計算|50|
|70|環境構築|50|
|71|競技プログラミング|49|
|72|MySQL|49|
|73|人工知能|49|
|74|maya|47|
|75|Linux|47|
|76|Windows10|46|
|77|Django2.0|45|
|78|VSCode|44|
|79|ROS|44|
|80|GitHub|44|
|81|Tkinter|43|
|82|gcp|43|
|83|備忘録|42|
|84|入門|42|
|85|linebot|42|
|86|seaborn|40|
|87|NLP|39|
|88|Ansible|39|
|89|C|39|
|90|pygame|39|
|91|word2vec|38|
|92|HTML|38|
|93|アルゴリズム|38|
|94|virtualenv|38|
|95|C#|36|
|96|画像認識|36|
|97|Scrapy|36|
|98|AtCoder|36|
|99|bottle|35|
|100|Stan|35|

#まとめ
「MachineLearning」と「機械学習」は同意、「DeepLearning」と「ディープラーニング」は同意など、とかにするという処理を加えれば、もう少し違った結果になりそうです。

また2019年6月末ぐらいに、タグ出現回数がどう変わるのか、確認してみたいと思います。
Pythonの抽象構文木をGraphvizで可視化する

# はじめに

Pythonには抽象構文木を扱う`ast`というモジュールがある。これを使って抽象構文木を可視化してみる。

# スクリプト

```parse.py
import ast
import sys

from graphviz import Digraph


def visit(node, nodes, pindex, g):
    name = str(type(node).__name__)
    index = len(nodes)
    nodes.append(index)
    g.node(str(index), name)
    if index != pindex:
        g.edge(str(index), str(pindex))
    for n in ast.iter_child_nodes(node):
        visit(n, nodes, index, g)


filename = sys.argv[0]
if len(sys.argv) > 1:
    filename = sys.argv[1]

with open(filename) as f:
    graph = Digraph(format="png")
    tree = ast.parse(f.read())
    visit(tree, [], 0, graph)
    graph.render("test")
```

# 実行

例えばこんなファイルを食わせる。

```test.py
def func(a, b):
    return a + b


def func2(a):
    print(a)

print("Hello")
```

```sh
$ python parse.py test.py
```

すると、こんな構文木が得られる。

![test.png](https://qiita-image-store.s3.amazonaws.com/0/79744/aa702be9-6873-4831-e8d3-d7ee3eb0bc92.png)

ちなみに引数を指定しないと自分自身をパースする。

```sh
$ python parse.py
```

得られる結果はこんな感じ。

![test.png](https://qiita-image-store.s3.amazonaws.com/0/79744/f50ba03b-82ef-d166-404e-dbfc2fff4e99.png)


# 動作原理

基本的には`ast.parse`で得られた木から再帰的にたどっていくだけ。`ast.iter_child_nodes(node)`で`node`にぶら下がるノードのイテレータが得られるので、それに対してforを回す。

Graphivzのノードのキャプションは`type(node).__name__`としたが、そのまま`g.edge`でつないでしまうと同じ名前が同じノードとみなされてしまうので、一工夫が必要。

そこで、ノードをリストに追加することで、それぞれに一意な通し番号をふる。


```py
    name = str(type(node).__name__)
    index = len(nodes)
    nodes.append(index)
    g.node(str(index), name)
```

で、この通し番号をGraphvizのノード番号として、繋げば良い。

```py
 g.edge(str(index), str(pindex))
```

最初は、オブジェクトをリストではなくハッシュに登録してたんだけど、抽象構文オブジェクト、例えば`ast.Load`はなぜか同じオブジェクトが使い回されているようで、同じノードとみなされてしまう。上記のように一意な通し番号を振れば大丈夫。
Slackの通知音「スッコココ」を変更する方法（Macアプリ版）

# 概要
1. 「スッコココ」の音はSlackアプリのパッケージに入っているknock_brush.mp3というファイルです
2. 該当のファイルを任意のmp3ファイルに差し替えることで通知音を変更することができます
3. macOS Mojave 10.14.2 + Slack 3.3.3で動作確認しました

# 手順
1. アプリケーション > Slackを右クリック > 「パッケージの内容を表示」をクリック
2. Contents > Resourcesディレクトリを表示させる
3. （オプション）元に戻したい時のためにknock_brush.mp3のオリジナルをどこかにバックアップしておく
4. knock_brush.mp3と同名のファイルに差し替える

# 参考画像
<img width="437" alt="slack_01.png" src="https://qiita-image-store.s3.amazonaws.com/0/52178/d7910ca4-6291-5ee5-cc2b-749c836064f4.png">
<img width="981" alt="slack_02.png" src="https://qiita-image-store.s3.amazonaws.com/0/52178/81c27b68-65d1-0f8d-38e3-14fa0d9c3851.png">

# サンプル効果音
自作した効果音のサンプルです。よかったら使ってみてください。
https://s3-ap-northeast-1.amazonaws.com/idacchi-public/qiita.com/5402c9eb04597aedee07/slack_se_1.mp3
https://s3-ap-northeast-1.amazonaws.com/idacchi-public/qiita.com/5402c9eb04597aedee07/slack_se_2.mp3
https://s3-ap-northeast-1.amazonaws.com/idacchi-public/qiita.com/5402c9eb04597aedee07/slack_se_3.mp3
https://s3-ap-northeast-1.amazonaws.com/idacchi-public/qiita.com/5402c9eb04597aedee07/slack_se_4.mp3
pandasでデータフレームの集約処理を超スマートに描く方法

### はじめに
データ前処理を行う際に、与えられる入力ファイルが複数に分かれている場合は
元となる情報に対して、トランザクション情報を集約・マージし一つのデータフレームとして扱うことが多々あります。
そのような問題に直面した時、以下のコードを参照してもらうと実装がスムーズに進むと思います。
※以下のコードはFabienDaniel氏による投稿を参考にしています。偉大な先駆者に感謝です。
引用元：https://www.kaggle.com/fabiendaniel/elo-world

## 集約処理

```python:script.py
import numpy as np
import pandas as pd
def aggregate(df):
    # 集約するカラムと集計方法を明記
    agg_func = {
        'a': ['sum', 'mean', 'max', 'min', 'std'],
        'b': ['mean'],
        'c': ['mean'],
    }
    
    agg_df = df.groupby(['id']).agg(agg_func)
    agg_df.columns = ['_'.join(col).strip() for col in agg_df.columns.values]
    agg_df.reset_index(inplace=True)

    df = (df.groupby('id')
          .size()
          .reset_index(name='count'))

    agg_df = pd.merge(df, agg_df, on='id', how='left')

    return agg_df

```

# 解説
上記の関数はpandasのデータフレームを引数として渡し、
関数内部のagg_funcに設定したカラムと集約方法でデータフレームにカラムを追加して返却します。
以下の実行例をご覧ください。
# 実行例

今回は、いい感じのデータがなかったのでデータを手作りしていきます。

```python:script.py

id_values = [1, 2, 3]
name_values = ['hiroyuki','taro','jiro']
my_dict = {"id": id_values, "name": name_values}
mst_df = pd.DataFrame.from_dict(my_dict)
mst_df
```
![WS000000.JPG](https://qiita-image-store.s3.amazonaws.com/0/273349/ed3a467c-2061-19ac-8cc1-6ce670e3cc99.jpeg)

上記はいわゆるマスタデータのようなもので、
カラムはid,nameの２つしかありません。
今回はhiroyuki,taro,jiroの３人分のデータです。
次にこの３人に対するトランザクションデータを作成していきます。

```python:script.py

id_values = [1,1,1,1,2,2,2,3,3,3]
a_values = np.random.rand(10)
b_values = np.random.rand(10)
c_values = np.random.rand(10)

my_dict = {"id": id_values, "a": a_values,"b":b_values,"c":c_values}
tran_df = pd.DataFrame.from_dict(my_dict)
tran_df
```

![WS000001.JPG](https://qiita-image-store.s3.amazonaws.com/0/273349/2247cd24-b81b-d80a-fd69-f29c672b242c.jpeg)

トランザクションデータはidをキーとして、a,b,cのカラムが存在します。
※a,b,cのカラムの集約値を取得していきます。
hiroyukiに対して4件、taroに３件、jiroに３件のデータを用意しました。
早速、先ほどの関数を使っていきます。

```python:script.py
tran_df = aggregate(tran_df)
tran_df
```
![WS000002.JPG](https://qiita-image-store.s3.amazonaws.com/0/273349/65c6ee71-c4a9-5b3a-d064-5cb503eaafe9.jpeg)

関数内部のagg_funcに対して指定した通りの集約が行われました。
カラム名は<strong>「集約元のカラム名_集約方法」</strong>となります。
最後に必要に応じて他のデータフレームとマージします。

```python:script.py
result = pd.merge(mst_df, tran_df, on='id', how='left')
result
```
![WS000003.JPG](https://qiita-image-store.s3.amazonaws.com/0/273349/dab34cec-03c3-65d0-9a3e-c85dbbf0de6d.jpeg)

以上です。

集約方法に関しては、大体今回使った以下の５つで事足りる場合がほとんどだと思います。
sum：合計値
mean：平均値
max：最大値
min：最小値
std：標準偏差
他にも使いたいという方はこちらを参照ください。
http://pandas.pydata.org/pandas-docs/stable/groupby.html
Rails・cookies永続化によるセッションハイジャックへの対策

Railsでは、sessionメソッドで保存した情報は自動的に安全が保たれるが、cookiesメソッドに保存する情報は残念ながらそのようにはなっていない。特に、cookiesを永続化すると、セッションハイジャックという攻撃を受ける可能性がある。この攻撃は、記憶トークンを奪って、特定のユーザーになりすましてログインするというもので、以下の4つの方法がある。

(1) 管理の甘いネットワークを通過するネットワークパケットからパケットスニッファという特殊なソフトウェアで直接cookieを取り出す。 
(2) データベースから記憶トークンを取り出す。
(3) クロスサイトスクリプティング (XSS) を使う。
(4) ユーザーがログインしているパソコンやスマホを直接操作してアクセスを奪い取る。


Railsチュートリアルでは、これらのセッションハイジャックに対して、以下の方法での対策を取っている。

**(1) 管理の甘いネットワークを通過するネットワークパケットからパケットスニッファという特殊なソフトウェアで直接cookieを取り出す。**
=>　Secure Sockets Layer (SSL) をサイト全体に適用して、ネットワークデータを暗号化で保護し、パケットスニッファから読み取られないようにする。

**(2) データベースから記憶トークンを取り出す。**
=> 記憶トークンをそのままデータベースに保存するのではなく、記憶トークンのハッシュ値を保存するようにします。

**(3) クロスサイトスクリプティング (XSS) を使う。**
=> Railsによって自動的に対策が行われる。具体的には、ビューのテンプレートで入力した内容を、すべて自動的にエスケープする。

**(4) ユーザーがログインしているパソコンやスマホを直接操作してアクセスを奪い取る。**
=> さすがにシステム側での根本的な防衛手段を講じることは不可能だが、二次被害を最小限に留めることは可能。具体的には、ユーザーが (別端末などで) ログアウトしたときにトークンを必ず変更するようにし、セキュリティ上重要になる可能性のある情報を表示するときは、デジタル署名 (digital signature) を行うようにする。

また、これらのセキュリティ上の考慮事項を元に、Railsチュートリアルでは次の方針で永続的セッションを作成している。

1. 記憶トークンにはランダムな文字列を生成して用いる。
2. ブラウザのcookiesにトークンを保存するときには、有効期限を設定する。
3. トークンはハッシュ値に変換してからデータベースに保存する。
4. ブラウザのcookiesに保存するユーザーIDは暗号化しておく。
5. 永続ユーザーIDを含むcookiesを受け取ったら、そのIDでデータベースを検索し、記憶トークンのcookiesがデータベース内のハッシュ値と一致することを確認する。

参考：[Railsチュートリアル](https://railstutorial.jp/chapters/advanced_login?version=5.1#cha-advanced_login)
よく使うGitコマンドのまとめ

初投稿。初心者向けです。
GItのコマンドをよく忘れてしまい確認する事が多いのと、やっていることの意味を再確認するために使用頻度の高いコマンドをまとめます

**よく使うコマンド**
```$ git init
$ git add .
$ git commit -m "メッセージ"
$ git remote add origin https://github.com/XXXX/XXXXXX.git
$ git push -u origin master
```

## **初期設定**
```$ git config --global user.name "XXXX"
$ git config --global user.email "XXXX@hogehoge.com"
```
まず最初にすること。
ユーザ名とメールアドレスの登録です。一回だけする。


## **リポジトリの作成**
```$ git init
```
プロジェクトのルートディレクトリにて、このコマンドを実行します。
このコマンドはGitのリポジトリを新たに作成するためのもので、既にあるリポジトリを再初期化するためのものでもある。

このコマンドが実行されると、「.git」と名付けられたサブディレクトリが作成されます。

## **リポジトリの作成**
```$ git add
```
作業帳ディレクトリの変更をステージングにあげるためのコマンド。
「**git add .** 」と「.」オプションを付ける事とで、全てのファイルをadd。
「**git add -u**」 は一つ前と最新のステージを比較して、変更があった部分のみをaddします。つまり、新しく作られたファイルはaddされません。
「**git add -A」**は「.」と「-u」を足したもので、新規作成、修正、削除といった全てのファイルをaddします。


## **リポジトリの作成**
```git commit -m "メッセージ"
```
addされてステージングエリアにあるファイルを、gitディレクトリにcommitするためのコマンド。
-mはcommitメッセージを付けるためのもの。-aを付けると全てのファイルをcommitする。


## **githubもしくはgitbucketへの追加**
```git remote add origin https://github.com/XXXX/XXXXXX.git
```
githubもしくはgitbucketをリポジトリのoriginとしてGitの設定ファイルに追加するためのもの。


## **リポジトリへのpush**
``` git push  origin master
```
ローカルのリポジトリをリモートのoriginにプッシュする。
`「git push -u origin ブランチ名」`など
`-u`オプションを付けると次回から `git push` だけで勝手に origin ブランチ名 で push してくれる。



## **Gitを理解するために重要な4つの段階**
上だけだとわからないと思うので、gitを使う上で大雑把な流れを記載します

- 作業ディレクトリ・・・ローカルで編集しているディレクトリ。自分が直接プログラミングしているファイルの場所。

**↓↓git add↓**

- ステージング・エリア・・・作業ディレクトリからaddされたファイルの集まり。commitするファイルを選択できる。

**↓↓git commit↓**

- Gitディレクトリ・・・commitされたファイルの集まり。remoteにpushすると反映される。

**↓↓git push↓**

- リモートリポジトリ・・・ネットソースコード。githubで見れる。pushされると反映される。
STU48が某個人配信プラットフォームで強いって言われてるけど・・・ その２の５

イベント前後でのフォロワー数の変化を示します。
イベント期間  2018/11/30 - 2018/12/09
データ 2018/10/25と2018/12/25
イベントの前後一ヶ月じゃねーか！

はい。何で残っていたのかわからないデータと、なんでもっと早くデータを集め始めなかったんだっていうデータの比較です。

特に何も考察しません。


#Follower多い順(2018/12/25時点)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/7aa8f9e0-42ec-3ea8-ad6a-7555fe981702.png)

#増加率

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/dbc7228b-bd91-1fc7-6cb5-a6acfe882e56.png)

#増加量
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180426/d9dca38f-5ec8-7105-ce7a-849cbc83e249.png)


#まとめ
みんな、瀧野由美子さんとコラボ配信するべき。人気はお裾分けしてもらうものだそうです。
とはいえ、他人だから簡単に言うけど難しいよね。
約１時間 世間話しとけと言われても。
SpringBootのDB初期化方法

# 標準の初期化

application.properties に初期化SQLを実行する設定を記述することにより、クラスパス直下のSQLファイルが存在すれば読み込んで実行される。

<em>▼ application.properties</em>

```properties

# ALWAYS ： アプリ起動時に毎回実行
# EMBEDDED ： 埋込DB(H2 Database)の時のみ実行
# NEVER ： 実行しない
spring.datasource.initialization-mode=always
```

alwaysを設定すると、毎回、SQLが実行される設定しているので、２回目以降の実行でエラーとならないSQLの工夫が必要。


<em>▼ SQLファイル一覧</em>

クラスパスの通っているディレクトリ ： src/main/resources/

```
schema-(platform).sql
schema.sql
data-(platform).sql
data.sql
ex) src/main/resources/*.sql
```

<em>▼ 工夫したSQL(PostgreSQL)</em>

```sql
-- 存在しない場合のみテーブルを定義
CREATE TABLE IF NOT EXISTS batch.hoge (
	id bigserial NOT NULL,
	name character varying(100),
	PRIMARY KEY(id),
	UNIQUE(name)
);

-- nameの一意制約発生を避けるため、ON CONFLICTを使用
INSERT INTO batch.hoge (name) VALUES ('taro')
ON CONFLICT ON CONSTRAINT hoge_name_key
DO NOTHING;

INSERT INTO batch.hoge (name) VALUES ('jiro')
ON CONFLICT ON CONSTRAINT hoge_name_key
DO NOTHING;

INSERT INTO batch.hoge (name) VALUES ('saburo')
ON CONFLICT ON CONSTRAINT hoge_name_key
DO NOTHING;

INSERT INTO batch.hoge (name) VALUES ('shiro')
ON CONFLICT ON CONSTRAINT hoge_name_key
DO NOTHING;
```

# DBマイグレーションによる初期化

標準の初期化では、２度目から「spring.datasource.initialization-mode=never」にするか、SQLに手間をかけなければなりません。
flywayなどを使えば、実行済みのSQLファイルは１度しか実行されないので楽になるはず。

<em>▼ pomx.xml</em>

```xml
<dependencies>
  <dependency>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-core</artifactId>
  </dependency>
</dependencies>
```

<em>▼ SQL実行ファイル例</em>

```bash
src/main/resources/db/migration/V0.0.1_schema.sql
src/main/resources/db/migration/V0.0.2_data.sql
```

# References

+ [Spring Boot - 85. Database Initialization](https://docs.spring.io/spring-boot/docs/current/reference/html/howto-database-initialization.html)
+ [spring boot を1.5系から2.0系にバージョンアップする](https://qiita.com/quartette/items/b5ba7a4b8a2c88220ece)
+ [Chapter 5. データ型](https://www.postgresql.jp/document/9.6/html/datatype.html)
+ [PostgreSQL 9.6.5文書 - INSERT](https://www.postgresql.jp/document/9.6/html/sql-insert.html)
+ [Flyway使い方メモ](https://qiita.com/opengl-8080/items/6368c19a06521b65a655)
画像などのバイナリファイルを uint8_t(1バイト符号なし整数形式)配列としてソースコードに埋め込む

# はじめに
ファイルシステムがない環境でのデバッグやライブラリに画像ファイルを埋め込見たい場合など･･･バイナリファイルをソースコードに組み込みたくなるケースが多々あります。

ソースコードへ組み込むには単純に対象ファイルを uint8_t 配列へ変換するだけで良いのですが、そのたびに変換方法を調べているので備忘録として残します。

#　コマンド

```bash
cat "file_path" | hexdump -v -e '8/1 "0x%02x, "' -e '"\n"' | sed -e 's/0x  ,//g' > data.txt
```

出力されたテキストファイルの中身をソースコードに貼り付けるなり、 下記のように配列の中で include してください。

```c
#include <stdint.h>

uint8_t array[] = {
#include "data.txt";
};

```


# 例
手っ取り早く、出力結果を見たい場合にどうぞ。httpbin から jpeg ファイルを落としてきて uint8_t 配列にしています。

```bash
curl http://httpbin.org/image/jpeg | hexdump -v -e '8/1 "0x%02x, "' -e '"\n"' | sed -e 's/0x  ,//g' > data.txt
cat data.txt
```

# reference
- https://qiita.com/aokomoriuta/items/949ef50bd21b15d10b76
    - 32bit 配列にしています。
- https://github.com/bitcoin/bitcoin/blob/master/src/Makefile.test.include#L216
    - この記事の元ネタ, bitcoin のユニットテストで json ファイルから uint8_t 配列を作成する処理になります。
ターミナルでディレクトリを参照する方法

ターミナルでpythonやjsなどのコードを実行する際には、そのコードを保存したディレクトリにたどり着く必要がある。
そのためにまずはディレクトリにたどり着くところから始める。
目当てのディレクトリがデスクトップのFlaskというディレクトリにありその中にhello.pyというファイルがあるとして、
今回はそのhello.pyを実行したいとする。そうすると以下のようになる。

cd Desktop #デスクトップを参照

cd Flask #Flaskディレクトリを参照

cd oython hello.py #hello.pyの実行
Hamcrest 2.1のリリース

## 概要

Hamcrest 2.1が2018/12/20にリリースされました。
これまでは複数のjarに分割されていたものが、1つのjarに統合されたようです。
公式サイトに、バージョン1.xからのバージョンアップ手順も公開されています。

[Hamcrest 公式サイト](http://hamcrest.org/JavaHamcrest/distributables#using-hamcrest-in-a-maven-project)

## 主な変更点

- 前述の通り、jarの提供方法が変わりました。
- org.hamcrest.Factory アノテーションが削除されました。

[Release Note hamcrest-2.1](https://github.com/hamcrest/JavaHamcrest/releases/tag/v2.1)

## pom.xmlの書き方

1つだけになったので単純です。

~~~xml
<dependency>
    <groupId>org.hamcrest</groupId>
    <artifactId>hamcrest</artifactId>
    <version>2.1</version>
    <scope>test</scope>
</dependency>
~~~

## build.gradleの書き方

1つだけなので単純です。

~~~gradle
apply plugin: 'java'

dependencies {
    testImplementation 'org.hamcrest:hamcrest:2.1'
}
~~~

## アップグレード時の注意点

JUnit4はhamcrest-core-1.3.jarに依存している為、そのままではmaven等でうまく依存関係を解消できません。その為、hamcrestでは中身の入っていないhamcrest-core、hamcrest-libraryをリリースすることでこの問題を解決するそうです。

その他のライブラリで同様にhamcrest-core-1.3に依存するものがあれば、下記のような対策を打つことになります。

build.gradleでは、以下のように書きます。

~~~gradle
apply plugin: 'java'

dependencies {
    testImplementation 'org.hamcrest:hamcrest:2.1'
    testImplementation 'org.hamcrest:hamcrest-library:2.1'
    testImplementation 'junit:junit:4.12'
}
~~~

pom.xmlでは、以下のように書きます。

hamcrest-libraryは他のdependencyより前に記載しないとhamcrest-library 2.1より古いバージョンが利用されてしまう、と公式サイトでは説明されています。

~~~xml
<dependencies>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest</artifactId>
        <version>2.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest-library</artifactId>
        <version>2.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>
~~~
Elmアーキテクチャは、如何にして状態を排除しているか

悟りを開いた気がするので、図にまとめました。

# 状態を排除する理由

![副作用と純粋関数.png](https://qiita-image-store.s3.amazonaws.com/0/140384/0c8141c3-2162-da73-e013-4d4304ab329c.png)
図中2段目は、入力値に対して出力値が一意に定まらない状態です。
即ち非純粋な関数です。
参照透過性がありません。
なので、色々困ります。
例えばテストがめんどくさいです。

図中3段目は、副作用が発生します。
こういうのも非純粋な関数なんですかね？
一応、入力値に対して出力値が一意ではあるんですが。
分からないので「？」としておきました。
とにかく、出力値以外の箇所への影響を考えないといけないので、色々困ります。
例えばテストがめんどくさいです。

というわけで、状態的なサムシングは全部入力値と出力値に集約させて、全部1段目にできたら良いね、というわけです。

# Elmアーキテクチャの仕組み

![The_Elm_Architecture.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140384/bac76f99-eafc-94a8-9936-385ba53d1730.png)


青色の部分が我々が書くコードの部分。
そして、この青い部分は、1つの大きな関数と見做すことができます。

![The_Elm_Architecture_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/140384/9430457f-379d-9154-60ef-e6e390589d9a.png)


黒い四角で表現しました。
状態とのやりとりを全部Elmランタイムが担い、入出力に集約させてるのが分かると思います。

# 書いてみて思ったこと

「状態」って表現がなんか不正確な気がする。
WTSQuerySessionでリモート接続元IPアドレスが取れない場合がある(RDGateway-NAT-RemoteApp)

#WTSQuerySession
XenAppやRemoteApp、はたまたRDPで接続元のIPアドレスをとるときに使うAPIです。
https://msdn.microsoft.com/ja-jp/library/cc429625.aspx
先日、以下の環境化にてIPアドレスが取れなくなり酷い目にあったので対処した方法を記載します。

#IPアドレスが取れない
RemoteApp構成の環境でIPアドレスが0.0.0.0や0.0.30.122とかわけのわからない値になる現象が発生。
環境を聞いたところ以下の構成になっていた。

ローカル端末→RDゲートウェイ→NAT変換→RemoteApp(Ap1) or RemoteApp(Ap2)

以下の場合は発生しない。

ローカル端末→NAT変換→RemoteApp
ローカル端末→NetScaler→NAT変換→XenApp(Ap1) or XenApp(Ap2)

なんでだろうな。と調査したところ
https://docs.microsoft.com/ja-jp/windows/desktop/api/wtsapi32/ns-wtsapi32-_wts_client_address

Remakeのところに、NATを使ってたり・VPN使うととれないよ。って書いてある。
これを突き付けて無理ですといったところ何とかしてくれないと困ると…

#解決策
一応これを使うことで回避できた。
https://docs.microsoft.com/en-us/windows/desktop/termserv/win32-tsgatewayconnection

WMIの機能みたいですが、残念なことにVB.NETでこのWin32-TSGatewayConnectionがうまく動かなかったので、PowerShellをVB.NETから起動して取るという荒業に。
※絞り込み条件はUSERNAMEを使いました。

RemoteAppは同一アカウントで先にログインしてるユーザは後にログインするユーザによって
はじき出される仕様なので理論的には一意になるはず。
一考するのであれば

 - WMIを起動できるアドミニストレータ権限のユーザの用意
 - 絞り込み条件にUSERNAMEを使うのであれば運用上問題ないことの担保を取る

以上を承知の上、試してみてください。
glTF 2.0 アニメーションのメモ

仕様はこちら

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations

glTF 2.0 でアニメーションできるのは

* tranlate
* rotate
* scale
* weight

のプロパティ(path)のみ. また, 変化させることができるのは node の transform(translate, rotate, scale) と, morph target の weight のみ

たとえばマテリアルのパラメータを変化させることはできない.

## animations

アニメーション(clip)の配列. たとえば ["run", "walk"] のような感じで animation clip を保持する.

animation は以下の変形させる channels の情報と, キーフレーム補間のための samplers の情報を持つ

## Animation sampler

input のアクセッサでキーフレームの時刻リストのありかを指定する(`input` という名称がわかりずらい...)
input accessor には min/max プロパティが入っている(キーフレームの区間)
また, アニメーションの単位は **秒**

input : キーフレーム情報を持つ Accessor のインデックス. Accessor は min/max(キーフレームアニメーションの区間)を持たなければならない. 
interpolation : 補間の形式(LINEAR, STEP, ...)
output : 各キーフレームに対応するアニメーションデータ(e.g. 回転　[10 度, 20 度, 30 度, ...])

たとえば AnimatedTriangle サンプルでは

https://github.com/KhronosGroup/glTF-Sample-Models/tree/master/2.0/AnimatedTriangle

min, max = [0.0, 1.0]
input count = 5
input = 0.0, 0.25, 0.5, 0.75, 1.0
(5 個のキーフレームで, 等間隔のキーフレーム)

output = rotation(VEC4) x 5 

となっています.

### Morph animation

`output` が morph weights の場合(後述の animation channel で接続関係がわかる)は, output の個数は input_count * weights の個数になります.

### Sparse accessor

morph target などは sparse accessor でメモリ効率よくしてくださいと仕様にあるが, どれくらい使われているか(glTF ビューアでサポートされているか)は不明.

## Animation channel

実際にアニメーションさせる node とそのプロパティ(path. e.g. translate, rotation, scale)を指定する.

sampler : 前述の, キーフレームアニメーションのための sampler.
target.node : アニメーション対象の node
target.path : アニメーションさせるプロパティ

## アニメーション値の復元

float ではない形式(8bit, 16bit データ)の場合は, 復元する式がきまっています.

https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#animations

## アニメーションの再生

時刻 `t` が与えられたときに,

```
for each channels:
  channel.sampler.accessor.min/max が min < `t` < max のときに
    channel.sampler.input のキーフレーム情報を参照し, 
    時刻 `t` に対するキーフレームと補間値を算出する
  
    channel.sampler.output からキーフレーム値を取得し補間し,
    それぞれの channels の target.path で指定したアトリビュートを変化
```


## Skinning(bone animation)

glTF 2.0 では, Skinning(bone)をサポートしているが, skinning ではボーンの構造を記述するのみである. ボーンをアニメーション変化させるには, animation を使ってまずは各ノードの行列を変化させたのち, ボーン階層を評価して最終的な頂点位置を求める.

## morph target との組み合わせ

T.B.W.
 
## glTF 2.0 animation 仕様のここがよくない

アニメーションデータは Buffer から Accessor 経由で取得しないといけないため, bin or DataURI でエンコードされているため, テキスト形式でアニメーション情報を確認したり調整したりができない.
AI FunctionをNode-REDから呼び出す

# はじめに
[Watson Machine LearningのAI Function機能を使って、SPSS Modelerの機械学習モデルをFunction定義する](https://qiita.com/makaishi2/items/ec91b98c04d6388bd0c0)の続編です。
上のリンクで作ったAI Functionのサービスを簡単に呼べる方法はないか、いろいろ考えてみて、
[Node-REDからWatson Studioの機械学習モデルを呼び出す](https://qiita.com/makaishi2/items/7324098233b119faa60c)みたいに、Node-REDの部品になっていると一番作る側は楽かと思いました。
オリジナルの部品に比べると相当低機能ですが、実際にそういうノードを作って、npmに公開しておきましたので、ご紹介します。

# Nodeの紹介

[node-red-contrib-ai-function](https://www.npmjs.com/package/node-red-contrib-ai-function)が、そのサイトです。せっかく作ったので、Webページの画面も紹介しておきましょう。

![スクリーンショット 2018-12-28 22.08.04.png](https://qiita-image-store.s3.amazonaws.com/0/206130/edac576f-133c-fb65-1f5a-3627efae6114.png)

自分のNode-RED環境にこのノードを追加する場合は[IBM CloudのNode-REDで追加ノードの導入手順](https://qiita.com/makaishi2/items/5c1e922352d6c30adaf0)の手順に従って下さい。

# 使い方

使い方はとても簡単です。ノードを編集画面に配置して、config nodeを設定する手順は
[Node-REDからWatson Studioの機械学習モデルを呼び出す](https://qiita.com/makaishi2/items/7324098233b119faa60c)とまったく同じなので、そちらを参照して下さい。
後は、Watson Studioの管理画面から、AI Functionの``Deployment ID``を取得して、下の画面のようにNodeの設定画面で設定します。ちなみに、「Mode」の項目は、前のNodeのときからそのまま残ってしまっていますが、今は「Run Function」しか選べないです。

![スクリーンショット 2018-12-28 22.15.03.png](https://qiita-image-store.s3.amazonaws.com/0/206130/ea427609-c180-8928-7b4e-3dcf5d2d7fa3.png)

``Deployment ID``はWatson Machine LearningのDeplotment管理画面の以下の領域に表示されているものを利用します。

![スクリーンショット 2018-12-29 12.13.08.png](https://qiita-image-store.s3.amazonaws.com/0/206130/c6e0684e-1469-6f6f-29ff-e0bbddc2591d.png)

あとは、下の図のように「inject」「function」「debug」の各ノードを編集エリアに配置し、一直線につなぎます。

![スクリーンショット 2018-12-28 22.20.33.png](https://qiita-image-store.s3.amazonaws.com/0/206130/99ea07a9-e793-9f82-5bcd-b01a1b58f951.png)

functionノードで入力用jsonを組み立てます。実装のサンプルは以下の通りです。「項目名」を意味する``fields``と「項目値」を意味する``values``を設定します。``values``の方は配列を二重にする必要があるので注意して下さい。

```
msg.payload = {
    "fields": ["CLASS", "AGE", "BP", "AL", "SC", "POT", "PCV"],
    "values": [[null, 75, 70, 0, 0.8, 3.5, 46]]
}
```
injectボタンをクリックすると、下のような結果が返ってくるはずです。

![スクリーンショット 2018-12-28 22.21.09.png](https://qiita-image-store.s3.amazonaws.com/0/206130/ae7b4414-41d4-e044-3bfb-78edef303137.png)![スクリーンショット 2018-12-28 22.21.17.png](https://qiita-image-store.s3.amazonaws.com/0/206130/6e6eb0b8-1c5e-8af9-a55c-bb7a5fb2b2cd.png)
【三項演算子で変数代入】

##【三項演算子で変数代入】
便利な使い方
①値を代入する時に、三項演算子を使う。
  
```rb

if boolean?
    var = '値1'
  else
    var = '値2'
  end
```

三項演算子を使うと、上のコードは以下のようになる。

```  var = boolean? ? '値1' : '値2'```
FOOBARキーボードを作る 【キーマップ】2018/12/29

まだ使ってないけど、空想的に良さそうなキーマップができた。
![FOOBAR_keyboard-layout_20181229.png](https://qiita-image-store.s3.amazonaws.com/0/283328/f52f3113-b28b-fc55-ede5-1db950b3374f.png)

```
/* Copyright 2018
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include QMK_KEYBOARD_H

enum foobar_layers {
  QWERTY,
  FN1,
  FN2,
  FN3,
  FN4,
};
#define LSFT_Z   LSFT_T(KC_Z)
#define LCTL_X   LCTL_T(KC_X)
#define LALT_C   LALT_T(KC_C)
#define FN4_V    LT(FN4, KC_V)
#define FN3_B    LT(FN3, KC_B)
#define FN2_N    LT(FN2, KC_N)
#define FN1_M    LT(FN1, KC_M)
#define RALT_BSP RALT_T(KC_BSPC)
#define RCTL_SPC RCTL_T(KC_SPC)
#define RSFT_ENT RSFT_T(KC_ENT)

const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {
  [QWERTY] = LAYOUT_split(
    KC_Q,   KC_W,    KC_E,    KC_R,    KC_T,    KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,
    KC_A,   KC_S,    KC_D,    KC_F,    KC_G,    KC_H,    KC_J,    KC_K,    KC_L,    KC_ESC,
    LSFT_Z, LCTL_X,  LALT_C,  FN4_V,   FN3_B,   FN2_N,   FN1_M,   RALT_BSP,RCTL_SPC,RSFT_ENT
  ),

  [FN1] = LAYOUT_split(
    KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_F1,   KC_F2,   KC_F3,   KC_F4,   KC_F5,
    KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_F6,   KC_F7,   KC_F8,   KC_F9,   KC_F10,
    KC_TAB,  KC_PSCR, _______, _______, _______, _______, _______, KC_DEL,  KC_F11,  KC_F12
  ),

  [FN2] = LAYOUT_split(
    KC_EXLM, KC_AT,   KC_HASH, KC_DLR,  KC_PERC, _______, _______, _______, _______, _______,
    KC_CIRC, KC_AMPR, KC_ASTR, KC_LPRN, KC_RPRN, _______, _______, _______, _______, _______,
    KC_TAB,  _______, _______, _______, _______, _______, _______, _______, _______, _______
  ),

  [FN3] = LAYOUT_split(
    _______, _______, _______, _______, _______, KC_MINS, KC_EQL,  KC_LBRC, KC_RBRC, KC_BSLS,
    _______, _______, _______, _______, _______, KC_COMM, KC_DOT,  KC_SLSH, KC_SCLN, KC_QUOT,
    KC_GRV,  _______, _______, _______, _______, _______, KC_LEFT, KC_UP,   KC_DOWN, KC_RGHT
  ),

  [FN4] = LAYOUT_split(
    _______, _______, _______, _______, _______, KC_UNDS, KC_PLUS, KC_LCBR, KC_RCBR, KC_PIPE,
    _______, _______, _______, _______, _______, KC_LABK, KC_RABK, KC_QUES, KC_COLN, KC_DQUO,
    KC_TILD, _______, _______, _______, _______, _______, KC_HOME, KC_PGUP, KC_PGDN, KC_END
  ),
};

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  return true;
}

void matrix_init_user(void) {

}

void matrix_scan_user(void) {

}

void led_set_user(uint8_t usb_led) {

}
```
VueJSでクソゲ−つくった

# きっかけ
[クソアプリAdvent Calendar](https://qiita.com/advent-calendar/2018/kuso-app)なるものを見かけて自分もクソゲーを作ってみたくなりました。クリスマスに間に合えばよかったのですが、完成したのがクリスマスの翌日だったのでやむなく通常の記事として投稿します。それにしても一人で過ごすクリスマスの開発の捗り具合は異常。

# 作ったもの
「炎上シュミレーター」https://enjo-simulator.netlify.com/
![Screenshot from 2018-12-27 22-31-02.png](https://qiita-image-store.s3.amazonaws.com/0/176789/78a698a6-3066-d9cf-c9c7-131deac7c372.png)

次々と流れてくるコメントを見て、アンチとファンを判別するゲームです。なんとなく「[通知止まらん](https://qiita.com/okumura_daiki/items/ed6398c06c1b40d10c6c)」アプリにインスパイアされた感じです。アンチのコメントをスパム認定できなかった場合、あるいはファンのコメントを誤ってスパム認定してしまうとメンタル崩壊ゲージが減っていき、０になるとゲームオーバーです。クリア条件とかは特に設定してないので、メンタル崩壊までのタイムを競う感じになります。難易度は流れるコメントの速さで３段階あります。

![Peek 2018-12-28 21-51.gif](https://qiita-image-store.s3.amazonaws.com/0/176789/b7080125-aee2-da81-6669-cfef1cfbb12a.gif)

# コード
JSフレームワークとしてVue.js, CSSフレームワークとしてVuetifyを使っています。
コメントの部分はVuetifyのListコンポーネントを使っておりこんな感じです。

```html
<v-list subheader>
<v-subheader>新着</v-subheader>
<v-list-tile
  v-for="item in new_comment"
  :key="item.name"
  avatar
  ripple
  @click="setSpam"
>
  <v-list-tile-action v-if="item.spam">
    <v-icon color="red">warning</v-icon>
  </v-list-tile-action>
  <v-list-tile-avatar>
    <img :src="item.avatar">
  </v-list-tile-avatar>

  <v-list-tile-content>
    <v-list-tile-sub-title v-html="item.name"></v-list-tile-sub-title>
    <v-list-tile-title v-html="item.comment"></v-list-tile-title>
  </v-list-tile-content>
</v-list-tile>
</v-list>
```

0.1秒ごとにsetIntervalを使って更新処理を行い、new_commentに要素が追加されるとコメントが増えます。タッチの検出はvueの@clickイベントで関数を呼び出して実現しています。

```javascript
update: function() {
  const parent = this
  setInterval(function(){
    parent.timeCounter += 100
    if (parent.timeCounter == parent.interval){
      parent.addComment()
      parent.timeCounter = 0
    }
  }, 100)
}
```

# 感想
Vue.jsはWebアプリケーション用で正直ゲームの開発には向かないと思うのですが、それを逆手にとってこういうゲームらしくないゲームも良いかなと思いました。処理効率がどうなってるかは怖くて調べたくないですが、正直開発する側としては普通のゲームエンジンを使うよりもコーディングがかなり楽です。ご意見ご感想お待ちしております。（アンチコメントはやめてね）
[Rails] link_to, url_for 違い、まとめ

rails link_to,url_for の　ビューヘルパーまとめ


#link_to
##使い方
`link_to(文字列, パス [, オプション, HTMLオプション])`

###オプション
|オプション  |概要|
|:-----|:----|
|:method|HTTPメソッド(:get, :post, :put, :delete)の指定|
|:remote|Ajaxでリンクを処理|
|:date|DATA要素 javascriptに関するパラメータ |
|HTMLオプション|id, class等

##使用例

###1,基本
```rb
<%= link_to "Home", myapp_path %>
```
```html:
#=>  <a href="/myapp">Home</a>
```

###2,コントローラーとアクションからURLを作成。
※引数リストの最後がHashリテラルの場合は{}を省略できる。

```rb
<%= link_to 'トップ' , {controller: :microposts, action: :show} , id: :link, class: :menu %>
```
```html
# => <a href ="/products/show" class="menu" id="link">トップ</a>
```

###3,HTTPメソッドを指定、クリック時にダイアログを表示

```rb
<%= link_to '削除する' , micropost_path(1) , method: :delete, data: {confirm: '実行しますか?' } %>
```
```html
#　=> <a data-confirm="実行しますか?" data-method="delete" href="/microposts/1" rel="nofollow">削除する</a>
```

###4,画像のリンク
link_toには、引数としてimage_tag（画像ファイルのパス）を持つこともできる

```rb
<%= link_to image_tag("home.png"), :action => "index" %>
```
```html
#=> <a href="/myapp"><img alt="Logo" src="/images/home.png"/ ></a>
```



#url_for

##使い方
`url_for(オプション)`
###オプション
|オプション  |概要|
|:-----|:----|
|:controller|コントローラー名|
|:action|アクション名|
|:host|URLのホストを指定	|
|:protocol|URLのプロトコルを指定|
|:anchor|アンカー(URLの#以降)を指定		|
|:only_path|trueなら、URL全体ではなくパス部分を返す|
|:trailing_slash|urlの最後にスラッシュを付けるか|
|:user|HTTP認証に使用するユーザー名|
|:password|HTTP認証に使用するパスワード|

##使用例
###1,基本url_forは現在のコントローラーを基点にURLを作成する

```rb
<%= url_for(action: :new) %> #現在のURL "/myapp/microposts/1"
```
```html
#=>  /microposts/new
```

###2,idなど、パラメータを指定

```rb
<%= url_for(controller: :microposts, action: :show, id: 1, anchor: 'rails' , charset: 'utf8' ) %>
```
```html
#=> /microposts/1?charset=utf8#rails
```

###3,only_path(絶対パス)

```rb
<%= url_for(controller: :users, action: :signup, only_path: false, protocol: 'https' ) %>
```
```html
#=>  https://localhost:3000/users/signup
```

###4,引数にオブジェクトを渡す

```rb
<% @micropost = micropost.find(1) %>
<%= url_for(@micropost) %>
```
```html
#=> /microposts/1
```


#参考
[Ruby on Railsドキュメント#lint_to](http://railsdoc.com/references/link_to)
[Ruby on Railsドキュメント#url_for](http://railsdoc.com/references/url_for)
[rails guide](https://railsguides.jp/routing.html)
[RailsTutorial](http://railstutorial.jp/chapters/filling_in_the_layout?version=4.2)
gulpコマンド一つでsassやjsをwatchしながらDjangoも立ち上げる

gulpと打つだけでjsとかsassのwatchをしつつDjangoのアプリケーションも立ち上げたい。


参考サイト
http://dae.me/blog/2111/run-django-dev-server-with-gulp/
https://gist.github.com/EtienneR/a7d9e956ace886516299

```gulpfile.js
'use strict';

const gulp = require('gulp');
const child = require('child_process');

var server = null;

gulp.task('server:spawn', () => {
  if (server && server !== 'null') {
    server.kill();
  }

  server = child.spawn('python', ['manage.py', 'runserver'], { stdio: 'inherit' });

  server.on('close', (code) => {
    if (code !== 0) {
      console.error('Django runserver exited with error code: ' + code);
    } else {
      console.log('Django runserver exited normally.');
    }
  });

});
gulp.task('default', ['server:spawn'])
```

アプリケーションの起動ってコマンド一つで動くのがあるべき姿だと思ってます。
複雑な手順だとデザイナーの方には難しいし、
手順が簡単だとちょっとHTML直すくらいだったら企画の人でもやってくれるようになる。
スタートアップとか人数少ないチームだとこういうのって結構重要な事なんじゃないかと。