OmniAICreator/Qiita-1.07M huggingface dataset:
Pythonの仮想環境にコマンドひとつで入りたい

pythonの仮想環境に入るには
`仮想環境\Scripts\activate`
といちいち打たなければなりません。
でもanacondaの`activate 仮想環境`みたいにコマンドひとつで入りたい。
そんなあなたにおすすめです。

今回はcmdファイルを使います。cmdファイルとはbatファイルと同様にコマンドプロンプトでの複数作業を一気にすることができるファイルです。
そのcmdファイルを新規のディレクトリに入れて、そこにパスを通してあげる作戦です。

#環境
Windows10 Pro
python==3.6.1

#手順
ここでは仮想環境をすでに作っているものとし、名前をvenvとします。

最初にcmdファイルを作ります。仮想環境を呼び出すときの名前になるのでここではvenv.cmdとします。

```venv.cmd
cmd /k C:\Users\(venvまでのパス)\Scripts\activate
```
cmdはコマンドプロンプトを開いて以下を実行するコマンドです。/kオプションをつけることで実行が終わった後もコマンドプロンプトを閉じずに開いたままにできます。　

次にあたらしく作ったディレクトリにこのvenv.cmdを入れます。ここではmysytemというディレクトリに入れることにします。

そして作ったディレクトリにパスを通します。
システム⇒システムの詳細設定⇒環境変数の順に開き、
その上のユーザーの環境変数の中のPathを開きます。
そこで新規に

```
C:\users\(mysystemまでのパス)\mysystem
```

を追加します。

#試してみる

コマンドプロンプトで実行してみます。

```コマンドプロンプト
>venv
(venv)>
```

きちんと仮想環境に入れていれば成功です!
お疲れさまでした。
php-master-changes 2018-11-28

今日は foreach の最後の行に対応するあたりのオペコードでの行番号の扱い修正、メモリアロケータのFreeBSD での Huge Page サポート、ドキュメントの修正があった！

# 2018-11-28
## nikic: Fixed bug [#76046](https://bugs.php.net/bug.php?id=76046)
- https://github.com/php/php-src/commit/d6595f276fff44aa5d1d2dde7238d540a267d0dd
- [7.2~]
- foreach の一時変数解放用にあるオペコード FE_FREE で、ソースコード中の対応する行番号が間違って出力されていた問題の修正
    - vld などのオペコードダンプや xdebug などで利用
- foreach の始まりと対応する行番号を付けるようになった
- 本来は foreach の最後の行と対応させるべきだが、現状 foreach の最後の行をとる方法がないための苦肉の策

## nikic: Improve fix for [#76046](https://bugs.php.net/bug.php?id=76046)
- https://github.com/php/php-src/commit/b565c85b9e166cbbc024ce279986b18e96048042
- [7.2~]
- ↑と同様に JMP 命令も foreach の始まりと対応する行番号を付けるようになった
- 本来はこちらも foreach の最後の行と対応させるべきだが、現状 foreach の最後の行をとる方法がないための苦肉の策

## devnexen: Support huge pages on FreeBSD
- https://github.com/php/php-src/commit/5d4938956a6ab3a61c7e98cd4613aeaa1e3943fe
- メモリアロケータで、FreeBSD でも [MAP_ALIGNED_SUPER](https://www.freebsd.org/cgi/man.cgi?query=mmap&sektion=2&manpath=freebsd-release-ports) を使って Huge Page をサポート

## cmb69: [ci skip] Add missing extension maintainership years
- https://github.com/php/php-src/commit/80e387cf6c0d64b3f253854161d8dc3438eda25b
- ext/xmlreader のメンテナの担当期間が抜けていたので追記
SourceTree (windows)で　git cloneするデフォルトのフォルダを変更する。

記事がなかったので自分で作ることにします。

git管理ツールは　人それぞれだと思いますが
SoureTree をつかってます。

デフォルトでgit clone してくると users 以下に設定されてしまうので
見づらくなってしまう場合、フォルダ位置を変更しましょう。

### 設定場所

[ツール]-[オプション]　を開いて  

[全般タブ]-[RepoSettings]内にあります。

[プロジェクトフォルダ]の欄を設定しましょう。

デフォルトは空欄になってます。


自分の設定したいパスに設定したらOKです！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/46608/0ea68806-d866-d61c-216a-cf7b48fe57c8.png)



よい、SourceTree ライフを！
デフォルト設定が人生を変える。優れたユーザーはUI UXの優れたサービスに集まる。

- 爆速で仕事したい人ほどデフォルト設定を愛する
- シンプルなUI/UXは時間価値の高いエンジニアほど貴重だ
- 多くのエンジニアがiPhoneを愛することになる
- 高いコンテンツ価値を提供するユーザーは、時間価値に敏感だ
- ソーシャルメディアであれば、高品質なコンテンツを投稿するユーザーを逃してはならない
- つまり他との競合において優れたUI UXを提供する必要がある
- 飲食店と同じでほんの少しの利便性の違いが大きな競争力となる
- UI UX は単にユーザー使い勝手ではなく、ソーシャル社会性を構築する大きな要因だ

[ui ux yumainaura - Google Search](https://www.google.co.jp/search?q=ui+ux+yumainaura&oq=ui+ux+yumainaura&aqs=chrome..69i57j69i60l3.2633j0j7&sourceid=chrome&ie=UTF-8)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
Qiita API v2を活用するときの参考記事まとめ

Qiitaが提供するAPIを活用する際によく参考に記事をまとめています。

自分用なので、自分記事が若干多めです。随時更新

この記事良かったよーとか、教えていただけると助かります。

## 公式

Qiita API v2ドキュメント - Qiita:Developer
https://qiita.com/api/v2/docs


## ライブラリ・ラッパー

【まとめ】Qiita API ライブラリ/ラッパー - Qiita
https://qiita.com/suin/items/857f839e894f5da787f8

Qiita API v2のPythonラッパー実装した - Qiita
https://qiita.com/petitviolet/items/deda7b66852635264508

PythonでQiita APIのCLIツールをさくっと作ってみた - Qiita
https://qiita.com/kai_kou/items/009d4b3d8a5cad3691ed


## Webサービス

Qiita版TweetDeck！？カラム形式でQiita記事をウォッチできるサービス「QiitaDeck」をリリースしました！ - Qiita
https://qiita.com/kazu1496/items/7ce5043f9128c9ab55f4

Nuxt.jsでQiita投稿一覧サービスを作る - Qiita
https://qiita.com/aytdm/items/0096e497837ec3aa8b35



## ツール

jq コマンドを使う日常のご紹介
https://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af

PC重たいのでターミナルでQiitaの記事検索・閲覧ツール[gota]を作った - Qiita
https://qiita.com/gorilla0513/items/d53ef65cb556201c3506

自分の Qiita 記事を自動英訳して Qiita/gist/Twitter へ投稿する Python スクリプトを作成してみた - Qiita
https://qiita.com/speaktech/items/f1c47ab15c17d873fd03

Qiita記事のいいね・Views・ストック数を取得するツールを作った - Qiita
https://qiita.com/developer-kikikaikai/items/b0a70362386698a1ea2d


## 活用

QiitaAPI v2の仕様を深堀し、使えるツールを作るための技術的要素を洗い出そう！ ～ただのパクリツールからの脱却へ - Qiita
https://qiita.com/developer-kikikaikai/items/037d38c16ac20a182e15

QiitaのAPIv2を使用して自身の記事取得 - Qiita
https://qiita.com/tatsuo-iriyama/items/c1e56c1a197e39087b6e

Qiita API v2を利用してcurlで投稿してみた - Qiita
https://qiita.com/kai_kou/items/663d3f7bbc4da4ccf62d

PythonでQiitaに予約投稿できるツールをさくっと作ってみた(使い方編) - Qiita
https://qiita.com/kai_kou/items/9129f0cc5249a039d11d

PythonでQiitaに予約投稿できるツールをさくっと作ってみた(環境構築編) - Qiita
https://qiita.com/kai_kou/items/e51ccf87e4ba1472780e

Qiita APIを利用して記事のViewsとストック数がまとめて取得できるAPIを作ってみた - Qiita
https://qiita.com/kai_kou/items/3f10ce93f4aa3b57b2d0

Qiita API v2で取得できる投稿のHTML形式の本文を利用してみた - Qiita
https://qiita.com/kai_kou/items/1bbf22180b741f189e0a

QiitaにVSCodeから直接投稿したい - Qiita
https://qiita.com/daichiiiiiii/items/493cf49e810eb5845547

自分の Qiita 記事を自動英訳して Qiita/gist/Twitter へ投稿する Python スクリプトを作成してみた - Qiita
https://qiita.com/speaktech/items/f1c47ab15c17d873fd03


## トラブル

Qiitaのコメント数表示がおかしくなったので調べてみた - Qiita
https://qiita.com/kai_kou/items/58e8e009b058ffaed6a3
プログラマは短気になれ！ 「ggrks ググレカス」「人に聞く前に自分で調べろ」って正気なの？

- 奥手で人見知りなオレたちエンジニアのエクスキューズじゃないの？
- 人に聞いたほうが千倍速い
- 人がカスタマイズする情報の高品質さ半端じゃない
- 熟練エンジニアの知見の深さ半端じゃない
- ふとした馬鹿な質問からこぼれ落ちてくる師匠の情報は宝石
- あなたの周りにいる人間はあなたに必要な情報を持っている
- 自分で調べるのはマナーは良いけどコスパ悪すぎ
- 人にコストをかけずに一瞬だけ5秒で出来る質問をしたら良いじゃない
- 人に質問したら相手も気分を良くするじゃない、人助けって楽しいし
- メンターと弟子の法則なら教える側に最大のメリットがある、教えることは最大のアウトプット、効果高し！質問は人のためならず。


[短気yumainaura - Google Search](https://www.google.co.jp/search?q=%E7%9F%AD%E6%B0%97yumainaura&oq=%E7%9F%AD%E6%B0%97yumainaura&aqs=chrome..69i57.3030j0j7&sourceid=chrome&ie=UTF-8)








<!-- Update From Qiita API -->

# チャットメンバー募集


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

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





# Twitter


https://twitter.com/YumaInaura


<!-- Update From Qiita API -->
AWS 支払い方法変更

2018/11/25時点のお話。
支払い方法を登録後、Supportへ連絡すればOKみたい。

```
海外送金払いからクレジットカード払いへの変更は、当窓口でおこなっております。
ご変更をご希望される際は、当窓口までお知らせくださいませ。
その際は下記URLにて、決済に使用されるクレジットカードをご登録の上、
複数のカードのご登録がある際は、設定ご希望のカード番号下4桁も併せてお知らせくださいませ。
https://console.aws.amazon.com/billing/home#/paymentmethods

限度額を超過されるなどで、初回(毎月3日頃を予定)の決済に失敗した場合は、
数日おきに再決済を行いつつ、およそ3回目の失敗以降は、お客様へ英文の自動送信メールにて状況をお知らせいたします。
当月中は決済が完了するまで、複数回決済を試行いたしますが、
当月中に完了しない場合は、アカウントがロックされる可能性がございますのでご注意くださいませ。

限度額の都合上、当月中に単一のカードでの決済ができない際は、
複数カードへ分割してのお支払いや、海外送金でのお支払いも、
当窓口で手配可能でございますので、ご希望される際はお知らせくださいませ。
これらのお手続きにはお時間をいただくこともございますので、
```
truffleでERC20トークンのtransfer関数をテストする．

## 概要
truffleを使ってMyTokenというERC20トークンを作成してみた．
そのテストを書いてハマったので備忘録を残す．


## 書いたテストスクリプト

最終的に以下のようなテストスクリプトを作成した．

```javascript:my_token_test.js
var MyToken = artifacts.require("./MyToken.sol");

contract('MyTokenTest', function(accounts) {

    it("should transfer MyToken", function() {
        var strage;
        return MyToken.deployed().then(function(instance) {
            strage = instance;
            //return strage.transfer(accounts[1], web3.fromWei(2000e18), {from: accounts[0]});
            return strage.transfer(accounts[1], 1000e18, {from: accounts[0]});
        }).then(function () {
            return strage.balanceOf(accounts[1])
        }).then(function(message) {
            //return assert.equal(message, 2000, "correct")
            return assert.equal(message, 1000e18, "correct")
            //return console.log(message)
        });
    });
});

```

## 何にハマったか
上のコードのコメントアウトしてあるところがポイント．
```balanceOf```関数を使って，```accounts[1]```に転送されたMyTokenの量をテストしたかった．
```1000e18```とは，転送にはWeiを用いて転送する量を設定するため，etherの単位に直すために```e18```をつけている．
この部分が曲者で，```console.log```を使って値を表示させていたのだが，なかなか思う通りの値が表示されていなくて非常に混乱しハマっていた（実際にはちゃんと転送されていた）．
ちなみに，上側のコメントアウトしてあるものを使用すると，Weiの単位での転送をしてくれる．
実用性があるのかは謎．
【コラム】MacのCPUがdockerに対応しているか確認する

# 概要
MacのCPUがdockerの要件を満たしているかを公式のページを見ながら確認する。

# まとめ
macのターミナルを開いて以下のコマンドを実行する。

```shell-session
$ sysctl kern.hv_support
```
実行結果には0か１が返却されます。
1の場合は　dockerに対応しているのですが、
０の場合はお使いのPCは要件を満たしていないため、
dockerをお使いになれません。
[超意訳]bitbucketにpushしたら何かすげぇエラーぽいのが出てきた件（2018/12版）

[前回の記事](https://qiita.com/htanaka0828/items/dcd093cd43ba7fcfe055)とはまた別のメッセージが出てきたので共有します
意外と反響あってbitbucket民多いんだなと思いました(小波感

# pushしたらエラーっぽい何かが出たんです
正確にはエラーっぽい何か
![image.png](https://qiita-image-store.s3.amazonaws.com/0/160396/43bcc056-a4fd-94da-ea66-d8a36dcf8dfa.png)

```
remote: Bitbucket Cloud will be disabling support for TLSv1 and TLSv1.1 effective 1 December 2018.
remote: Please make sure your TLS version is updated.
remote: For more info: https://bitbucket.org/blog/deprecating-tlsv1-tlsv1-1-2018-12-01
```

# とりあえず出てきたURLを見てみる
こちらです
https://bitbucket.org/blog/deprecating-tlsv1-tlsv1-1-2018-12-01

## 英文をざっくり読んでみる
> Deprecating TLSv1 and TLSv1.1

「TLSのバージョン1とバージョン1.1を非推奨にするぜ！」ということらしいです。
もし使っている人がいたらアップデートしてくれよな！っていうのが今回の勧告の内容です。
どんな人が影響あるとかどういうところを確認してくれとか書いてありますが順番にざっくり見ていきましょう。

## 対応期限
英文をじっくり読み込む前に、いつまでに対応が必要かを知っておきたいところです。
今回の期限は

> 1 December 2018.

2018年12月1日からTLSのバージョン1と1.1は非推奨になります。

## 確認したいこと
今回は「85%の人には影響がない」と書いてあります。
逆に言うと対象者は15%程度ということなのでちゃんと確認しておいた方が良さそうです。

確認して欲しいこととして挙がっているのは以下の5つです。
> ・Git or Mercurial traffic to bitbucket.org
> ・The bitbucket.org Web interface
> ・API calls to api.bitbucket.org
> ・Hosted sites on bitbucket.io
> ・Any other HTTPS traffic not listed here

* 「bitbucket.org」にGitかMercurialで接続している人
* 「bitbucket.org」にwebでアクセスしている人
* 「api.bitbucket.org」のAPIを呼んでいる人
* 「bitbucket.io」のホストされたサイト
* その他の色々なHTTPSトラフィックが発生する何か

つまりは
「bitbucketに対してhttpsでアクセスしている人たちは影響がある可能性があるから確認してね」
ということです。

### 除外対象
> How can I tell if I will be affected by this change?

の項に何を確認すれば良いか、という事が細かく例示されています。
開発者として一番気になるのは「ある日pushできなくなるんじゃないか」というところです。
一番上に一番確認しやすい項目が書いてあります。

> SSH connections to Bitbucket are unaffected.

「SSHの接続は影響ないぜ！」ということらしいです。
確認してみます。

```
local@hoge:/project/fuga_git$ git remote -v
origin  git@bitbucket.org:hoge/fuga_git.git (fetch)
origin  git@bitbucket.org:hoge/fuga_git.git (push)
```

アドレスはサンプルです。
`git@bitbucket` の形であればhttpsアクセスではないので今回は対象外ということになります。
逆に `https://` からのアドレスであればTSLのバージョンの確認が必要ということになります。

## 確認対象を確認する
色々と書かれていますが、最後の方にこんな一文があります。
> we don’t have enough room here to list all the different combinations, unfortunately, but we hope that the “will I be affected” section can point you in the right direction.

超ざっくり言うと
「スペースが無いから全ての対象をリストアップするのは無理だけど『影響の確認』のところを参考にしてくれよな！」
という事がかいてあります。
『影響の確認』というのが、中盤にある

> How can I tell if I will be affected by this change?

の項と思われます。
戻ってリストを確認してみましょう。

* ブラウザからのアクセス
* Bamboo, Jenkins, Jira Server, Confluence Server, そのほかjavaベースのシステムたち
* GitとかMercurialのGUIツール（例えばSourcetree）
* GitのCLIツール
* MercurialのCLIツール
* API clientツールを使っているならコネクションライブラリを確認しておきなさい

詳細が知りたい方は英文をよく読んでみてください。
あらゆるところにhttpsアクセスの可能性があるから注意深く確認する必要があるよ！ということです。

## 結局よくわからないから誰か助けて！

> As always, please contact our support team if you need additional information.

「困ったらサポートチームにいつでも相談してくれよな！」とフランクに書いてくれています。
困ったら相談しましょう。

# まとめ
2018/12/1まであと少しですが、サクッと確認をしておきましょう。
もし対象を見つけたらSSHのアクセスに切り替えるのかTSLのバージョンを上げれば解決です。
この記事も注意喚起の期間が終わったら過去の遺物として編集する予定です。
よろしくどうぞ。
寝屋川市工業会 知らないと損する！　企業のＩｏＴ技術の取り込み方

#概要
- 日時：2018.12.04 18:00-19:30
- 会場：ニューコマンダーホテル　別館おるろーじゅ

#講演タイトル
- 知らないと損する！　企業のＩｏＴ技術の取り込み方

#ICTの動向
- [経済産業省　資料　２０１７．３](http://www.chusho.meti.go.jp/koukai/kenkyukai/smartsme/2017/170329smartsme05.pdf)

#IoTの実例集
- [スマートIoT推進フォーラム](https://smartiot-forum.jp/iot-val-team/iot-case)
- [ロボット革命イニシアチブ協議会]（https://www.jmfrri.gr.jp/info/rri/380.html ）
- [日立システムズ](https://www.hitachi-systems.com/ind/fs/pioneer/report/report01/)
- [東芝のIoT](https://www.toshiba.co.jp/iot/usecase/index_j.htm?utm_source=google&utm_medium=cpc&utm_campaign=search)
- [FANUC](https://www.fanuc.co.jp/ja/product/video/field.html)

# 精密プレス工業　カウンタ　動画
- [精密プレス工業](https://www.youtube.com/channel/UC-Mg3os-eI3AKRDs0ffMPYQ)
- [打点カウンタ：基本動作](https://www.youtube.com/watch?v=N-AbjdU-BFw)
- [レーザー加工機：タイマ](https://www.youtube.com/watch?v=euLpMJSWL28)
- [スポット溶接：実際の映像](https://www.youtube.com/watch?v=QtY1P7T86Oo)

#衝撃動画
- [NHKで紹介「中小機構　退職　動画」：Youtube](https://youtu.be/ihw3eyzaT7E)
- [中小機構：「生産性向上」特設サイト](https://seisansei.smrj.go.jp)

#中小機構おすすめアプリ
- [出退勤アプリ：IEYASU](https://www.ieyasu.co)
- [レジアプリ：スマレジ](https://smaregi.jp)
- [会計管理システム：MFクラウド](https://biz.moneyforward.com)

#IEYASU
- [土井研究室](https://ieyasu.co/doilab)

#IFTTT
- [IFTTT](https://ifttt.com)

#自動翻訳
- [自動翻訳してくれるブラウザ：Chrome](https://www.google.com/intl/ja_ALL/chrome/)

#Google Form
- [Google drive](https://www.google.com/intl/ja_ALL/drive/)
- [Googleアカウントの取得方法](https://www.ajaxtower.jp/googleaccount/new/index1.html)
- [QRコードの作成](https://qr.quel.jp/form_bsc_url.php)

# 身近なIoTの商品
- []()
- [tile Mateの紹介](https://kinfumi.com/category/recommended-info/tilemate/)
Tweepy で 特定ユーザーのツイートを取得

```py:get_tweet_tweepy.py
#! /usr/bin/python
#
#	get_tweet_tweepy.py
#
#						Nov/29/2018
# ------------------------------------------------------------------
import	sys
import	tweepy

from key_tweepy import key_tweepy_proc

sys.stderr.write("*** 開始 ***\n")

api = key_tweepy_proc()

results = api.user_timeline(screen_name="ekzemplaro", count=10)
#
for result in results:
	print(result.id)
	print(result.created_at)
	print(result.text)
	print()
#
sys.stderr.write("*** 終了 ***\n")
# ------------------------------------------------------------------
```

key_tweepy.py はこちらと同じです。
[Tweepy で Twitter の単語を検索する](https://qiita.com/ekzemplaro/items/92bf8f680b7667f028d5)

Teepy の API の仕様です。
[API Reference](http://docs.tweepy.org/en/3.7.0/api.html)
Vagrantの起動から終了まで（Windows）

ローカル開発環境を構築しましたが、使用するのに不慣れなので、今回は知識の定着のために仮想マシンの起動から修了までの流れをアウトプットしていきたいと思います。

###動作環境
ターミナル
・Windows PowerShell
・FTP
・Cyberduck
仮想マシンとツール
・Vagrant
・Vitual Box
フォルダ
C:/MyVagrant/MyCentOS
開発ファイル（仮想マシン下）
home/vegrant/php_lessons/index.php

####1.起動
仮想マシンを動かすフォルダに移動します。
VagrantfileがあるフォルダにPowerShellを使って移動します。


```
cd MyVagrnt
```

```
cd MyCentOS
```

仮想マシンを起動します。

```
vagrant up
```

（補足）状態を確認

```
vagrant status
```

runningと出力されると、起動に成功しています。


仮想マシンにログインします。

```
vagrant ssh
```

$よリ前のコンピューター名の箇所に[vagrant@localhost ~]表示されていれば接続成功です。


####2.開発
CyberduckのようなFTPソフトを使って仮想マシン内のファイルを確認できます。
PowerShellでもできましたが、仮想マシン下ではputtyの方が都合が良いようです。

```
cd  php_lessons
```

webサーバーを立ち上げます。

```
php -S 192.168.xx.xx:8000
```
IPアドレス部分は、開発環境を構築したときにVagrantfileで決めた値を入力します。

````
http://192.168.xx.xx:8000
```

このようにURLが出力されるのでブラウザでアクセスすると、開発ファイルであるindex.phpを確認できます。


####3.終了
開発が終わったら、サーバーを立ち上げたターミナル上で、「Ctrl-c」でサーバーを終了します。

仮想マシンからログアウト

```
exit
```

仮想マシンの終了

```
vagrant suspend
```


ご覧いただきありがとうございました。
[JavaScript][CSS] グレースケールの表示

画像のグレースケールについて紹介します。（2018年11月現在）

```Markdown:動作環境
OS: Windows 10 Pro
Google Chrome: 70.0.3538.110
Mozilla Firefox: 63.0.3
Microsoft Edge: 42.17134.1.0
Microsoft Internet Explorer: 11.407.17134.0
```

# グレースケールとは
グレースケールとは、画像を白色から黒色までの明暗で表現したものです。ここでは、通常の画像を用意して、Webアプリ上で画像をグレースケール化する手法を紹介します。

以下のデモページを表示してみてください。
[デモページはこちら](https://yunbow.github.io/sample-javascript-api/grayscale/)
[ソースファイルはこちら](https://github.com/yunbow/sample-javascript-api/tree/master/grayscale/)

「method」カラムにグレースケールの手法、「source」カラムに元の画像、「result」カラムにグレースケール化の画像を表示しています。以下に、3つの手法について紹介します。

#### CSS filter
1つ目は、CSSの`filter`プロパティを使用する方法です。3つの内、最もスマートに実装できます。しかし、IE11では動作しません。

```css:index.css
img#test1 {
    filter: grayscale(100%);
}
```

|ブラウザ名|動作可否|CSS filter|
|:--|:--|:--|
|Google Chrome|○|表示される|
|Mozilla Firefox|○|表示される|
|Microsoft Edge|○|表示される|
|Microsoft Internet Explorer|×|表示されない|

#### SVG
2つ目は、SVGの`filter`を使用する方法です。HTMLに直接SVGを組み込むか、CSSの`filter`プロパティに指定することができます。実装コードが多くなります。

```css:index.css
img#test2 {
    filter: url("data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg"><defs><filter id="grayscale"><fecolormatrix type="matrix" values="0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0.3333 0.3333 0.3333 0 0 0 0 0 1 0"></fecolormatrix></filter></defs></svg>#grayscale");
}
```

|ブラウザ名|動作可否|SVG|
|:--|:--|:--|
|Google Chrome|×|表示されない|
|Mozilla Firefox|○|表示される|
|Microsoft Edge|×|表示されない|
|Microsoft Internet Explorer|×|表示されない|

#### HTML canvas
最後は、HTML canvasを使用する方法です。

```javascript:index.js
grayscale($("#test3"))

function grayscale(selector) {
    var canvas = document.createElement('canvas');
    var canvasContext = canvas.getContext('2d');
    var img = new Image();
    img.onload = function () {
        var imgW = img.width;
        var imgH = img.height;
        canvas.width = imgW;
        canvas.height = imgH;

        canvasContext.drawImage(img, 0, 0);
        var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

        for (var y = 0; y < imgPixels.height; y++) {
            for (var x = 0; x < imgPixels.width; x++) {
                var i = (y * 4) * imgPixels.width + x * 4;
                var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3;
                imgPixels.data[i] = avg;
                imgPixels.data[i + 1] = avg;
                imgPixels.data[i + 2] = avg;
            }
        }

        canvasContext.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height);
        selector.attr("src", canvas.toDataURL());
    };
    img.src = selector.attr("src");
}
```

|ブラウザ名|動作可否|HTML canvas|
|:--|:--|:--|
|Google Chrome|○|表示される|
|Mozilla Firefox|○|表示される|
|Microsoft Edge|○|表示される|
|Microsoft Internet Explorer|○|表示される|

全てのブラウザで動作する手法は、「HTML canvas」になります。

# 引用
[[Javascript][CSS] グレースケールの表示](https://ameblo.jp/softwaredeveloper/entry-12333587437.html)
てすと

```python
"""
Created on Mon Nov 26 23:40:35 2018

@author: jin
"""

import numpy as np
import tensorflow as tf
import tensorflow.contrib.slim as slim
import tensorflow.contrib.learn as learn
import copy
from tensorflow.contrib.learn.python.learn.metric_spec import MetricSpec

x = tf.placeholder(tf.float32, shape=[None, 784])
y = tf.placeholder(tf.float32, shape=[None, 10])


def cnn_model(x,y):
    x = tf.reshape(x,[-1, 28, 28, 1])
    y = slim.one_hot_encoding(y, 10)

    with slim.arg_scope(
        [slim.conv2d],
        #活性化関数
        activation_fn=tf.nn.relu,
        #重み
        weights_initializer=tf.truncated_normal_initializer(stddev=0.1),
        #バイアス
        biases_initializer=tf.constant_initializer(0.1)
    ):
        with slim.arg_scope([slim.max_pool2d], padding='SAME'):
            #畳み込み層1
            c1 = slim.conv2d(x, 32, [5,5])
            #プーリング層1
            p1 = slim.max_pool2d(c1, [2,2])
            #畳み込み層2
            c2 = slim.conv2d(p1, 64, [5,5])
            #プーリング層2
            p2 = slim.max_pool2d(c2, [2,2])
            #全結合層
            p2_flat = slim.flatten(p2)
            fc1 = slim.fully_connected(p2_flat, 1024)
            #dropout
            #prob = tf.placeholder(tf.float32)
            #dropout = slim.dropout(fc1, prob)
            #読み出し層
            fc2 = slim.fully_connected(fc1, 10, activation_fn=None)

            prob = slim.softmax(fc2)

            cross_entropy = slim.losses.softmax_cross_entropy(prob, y)

            train_step = tf.train.AdamOptimizer(1e-4).minimize(cross_entropy)


    return prob,cross_entropy,train_step


mnist_o = np.genfromtxt(r'C:\Users\jin\Desktop\digits.csv', delimiter=",")
#1列目を消去
mnist = np.delete(mnist_o,[0],0)
#ラベル列の分離
mnist_label,mnist_data = np.hsplit(mnist,[1])
#学習行とテスト行のsplit
x_train, x_test = np.vsplit(mnist_data,[8000])
y_train, y_test = np.vsplit(mnist_label,[8000])

tf.logging.set_verbosity(tf.logging.INFO)
validation_metrics = {
    "accuracy" : MetricSpec(
        metric_fn=tf.contrib.metrics.streaming_accuracy,
        prediction_key="class")
}
validation_monitor = learn.monitors.ValidationMonitor(
        x_test,
        y_test,
        metrics=validation_metrics,
        every_n_steps=100)

classifier = learn.Estimator(model_fn=cnn_model, model_dir='/tmp/cnn_log',
    config=learn.RunConfig(save_checkpoints_secs=10))
classifier.fit(x=x_train, y=y_train, steps=3200, batch_size=64,
    monitors=[validation_monitor])
pipでインストールしたコマンドをUbuntuで使えるようにする

# 現象
Ubuntuのaptで入れたpipでpyinstallerをインストールし、実行しようとしたところ何故かうまく行ってなかった
というかpipで入れたコマンド全般が動いてない様子

```shell
$ pip install pyinstaller
〜中略〜
$ pyinstaller
pyintaller: command not found
```

# 原因と対処法

どうやらパスが通ってなかったらしい
というわけでパスを通せば解決する。

```shell
$ PATH=${PATH}:${HOME}/.local/bin
```
プログラム初めて1週間だけどエクセルを自動化する

ruby 超入門を1週ざっと読んだので、練習がてら何か動くものを作りたい。
ちょうど月末だったので、勤務実績をエクセルに書く定型処理を自動化する。

#七転八倒
"ruby excel"でぐぐって、以下のページなどを参考にrubyXLというgemを使おうと思った。
https://qiita.com/m-shin/items/fc6f551da921e00df54d

が、会社PCではgem installコマンドがうまく動かない。たぶんプロキシが動いてるか、ファイアウォールで邪魔されているか。。。
--localオプションも試してみたけど、20分くらい試してみてなんか上手くいかなかったし、gemをネット接続なしで入れるのは茨の道と各所で散見されたので、本筋でもないし諦めることに。

win32oleというライブラリが標準で使えるらしいし、サンプルコードを試したら動いたので採用することに。

やること：とりあえず動くものを作る。最初はハードコーディング上等。徐々に機能を増やす(ファイル自動で見つけてきたりだとか)。
やらないこと：綺麗にかく

実際にコード書き始めたら、if文、case文の書き方とか、eachメソッドの書き方とかすら頭に入ってなかったことが判明。
とりあえずエラーを出して何行目が間違っているか確認しながら進行中。
#現状のコード

```
excel.rb


#! ruby -Ks
require 'win32ole'


def get_shift #シフト表から当月のシフトを取得

  app = WIN32OLE.new('Excel.Application')
  
  fso = WIN32OLE.new('Scripting.FileSystemObject') #pathで指定したいときはこの2行
  book = app.Workbooks.Open(fso.GetAbsolutePathName('2018-12-Ver01.xlsx')) 
  
  #book = app.Workbooks.Open(app.GetOpenFilename)
  #手動でファイルを指定するときはこれ


  begin  #メインの処理ここから

    sheet = book.Worksheets('2018年11月シフト')  #目標のシートをハードコーディング。。。
    
    @shift = sheet.Range('C6:AG6').Value        #目標セルをハードコーディング。。。
  


         #メインの処理ここまで

  ensure
    book.Close
    app.quit
  end

end


def timecard

  app = WIN32OLE.new('Excel.Application')
  fso = WIN32OLE.new('Scripting.FileSystemObject')
  
  book = app.Workbooks.Open(fso.GetAbsolutePathName('timecard_20181128.xlsx'))

  begin  #メインの処理ここから
  
  sheet = book.Worksheets(1)
  x ="C"
  y =5
  cell = sheet.Range(x + y.to_s)
  
  for i in @shift do
    case i
      when "N1"
        x = "C"
        cell.value = "1"
        x = "A"
        cell.value = "9:00"
      when "N2"
        x = "C"
        cell.value = "2"
        x = "A"
        cell.value = "17:30"
        x = "B"
        cell.value = "2:00"
      when "N3"
        x = "C"
        cell.value = "3"
        x = "A"
        cell.value = "1:00"
      when "休"
        x = "C"
        cell.value = "公休"
    end
    
    y += 1
    
  end
  
  book.save
         #メインの処理ここまで

  ensure
    book.Close
    app.quit
  end
end



```
会社で夜勤の暇な時間でしこしこやってたら、get_shiftメソッドは動くようになった。

帰ってきて家のPCでtimecardメソッドがある程度できてきたから、試しに動かそうとしたら、以下のエラー。
initialize': unknown OLE server: `Excel.Application' (WIN32OLERuntimeError)

家のPCにエクセルいないもんね。そりゃそうだ。。。
開発環境はCloud9を使って、試すときは1回ローカルに落としてってやってたけど、すぐに動作確認できないのは面倒だなぁ
M5StackとUnity間でBluetoothシリアル通信をしよう

#

最近話題になってるM5StackにはBluetoothモジュールが標準で付いてます。
これ一個あればUnityで開発できるゲームの幅が広がるなぁと思い、Unityと通信しようとすると結構つまずいたので、方法を共有しようと思います。

この記事内では、M5Stackで取得した情報を、Bluetoothシリアル通信でPCに送ってUnityで取得するまでをやります。


#---開発環境---
1. Unity2018.2.15f1
2. M5Stack Basic
3. Arduino IDE 1.8.7
4. UniRx

#M5Stack側準備
Bluetooth通信回りは、**[BluetoothSerial.h](https://github.com/espressif/arduino-esp32/blob/master/libraries/BluetoothSerial/src/BluetoothSerial.h)**というライブラリを使ってやります。
M5Stackの最初のセットアップでこのライブラリは追加されていると思いますが、見つからない場合はインストールしなおしてください。

下のプログラムはM5Stackで0から255までの数字を0.1秒おきにBluetoothでPCに送るプログラムです。これをArduino IDEのスケッチに書いてください。
コンパイルして問題がなければ、選択してるボードとシリアルポートが間違えてないか確認して、M5Stackに書き込みましょう。


```ruby:BluetoothTest
#include <M5Stack.h>
#include "BluetoothSerial.h"


byte counter;

BluetoothSerial bts;

void setup() {
  M5.begin();
  M5.Lcd.println("Bluetooth Now");

  Serial.begin(9600);
  bts.begin("M5Stack");//PC側で確認するときの名前

  counter = 0;
}

void loop() {
  bts.println(counter);
  counter++;
  delay(100);
}
```

ここで一度シリアルモニタでちゃんとBluetoothでシリアル通信できてるか確認しましょう。
Windowsならば、```設定>デバイス>Bluetoothとその他のデバイス```　を開き、Bluetoothデバイスを追加しましょう。
デバイスの名前は**M5Stack**になってます。
無事に接続できたら、コントロールパネルからデバイスマネージャーを開き、ポートを確認してください。
確認すると、Bluetoothリンク経由の標準シリアル(COMn)という名前でポートが二つ開かれているはずです。
![bandicam 2018-11-29 03-15-41-464.jpg](https://qiita-image-store.s3.amazonaws.com/0/281560/611c3434-1ef8-0d35-5926-69f27ca766d4.jpeg)
ここでなんで二つポートが開くかまだ理解してないんですよね...（すみません:sweat:）
とりあえず小さい方の数字のポートを、ArduinoIDEのシリアルポートで選択してください。
そしたらシリアルモニタを開いて、ボーレートを9600bpsにして、1から255までの数字が表示されていれば成功です。無事にPCとBluetooth経由でシリアル通信ができました。
もしも何も表示されなければ、もう一つのポートを選択して同じことをやってみてください。

#Unity側準備
それではUnity側の準備です。
ここの準備は、[下記の引用サイト2のおもちゃラボ様の記事内](http://nn-hokuson.hatenablog.com/entry/2017/09/12/192024)まんまです。
記事内の**Unity側のプログラムを作る**に書かれていることをそのまま実行してください。


#実行してみる
これもおもちゃラボ様の記事内通りなんですが諸々補足。
最後の、Unity内のコンソールビューで、何度実行しても何も表示されない、または```can not open serial port```となる時があるんですが、これは単純にArduinoIDEのシリアルモニタを出しっぱなしにしてるのが原因かもしれません。シリアルモニタを閉じて再度やってみましょう。



#未解決の課題

1. なんで一個のM5Stackでポートが二つ開くのか。
2. M5Stackを二つ使って、Unity側で二つのデータを受け取ろうとすると不安定過ぎて使い物にならない。


2の問題についてなんですが、
M5Stackを二つ使って、Unity側で二つのデータを受け取るということをやってみました、10回に1回くらいは無事にデータを取得できるんですが、ほとんどは片方のデータしか取れなかったり、両方とも取れなかったりします。

1,2とも原因がわかり次第追記します。

#開発、執筆にあたり、下記のサイト様を参考、引用させていただきました。
　
1. [【Unity】UniRxを使ってArduinoとシリアル通信 - おもちゃラボ](http://nn-hokuson.hatenablog.com/entry/2017/09/12/192024)
2. [SerialPort または Uniduino を使った Unity と Arduino を連携させる方法調べてみた](http://tips.hecomi.com/entry/2014/07/28/023525)
3. [ESP32でBluetoothSerial通信をしよう！](https://blog.rogiken.org/blog/2018/04/11/esp32%E3%81%A7bluetoothserial%E9%80%9A%E4%BF%A1%E3%82%92%E3%81%97%E3%82%88%E3%81%86%EF%BC%81/)
応答遅延をシミュレートする簡易モックサーバをNode.JSでWindowsローカルに立てる

## 動機

JMeterやLocust、Gatlingなどの負荷試験ツールで負荷試験を行う際、「このツールのこういう挙動ってどうなってるんだっけ？」というのをちょちょいと検証したいと思う瞬間がよくあります。

そういうときにお誂え向きのサーバなどがあればよいのですが、あれこれ準備せずサクっと容易したいときにはNodeJSでローカルにサーバを立てるのが一番お手軽だと思いやってみました。車輪の再発明上等。

## やりたいこと

* getパラメータに応じた遅延時間をシミュレートするWebサーバ
* 任意のURLを拾って最低限のJSONレスポンスを返す
* 処理時間と受けたタイムスタンプぐらいはコンソールで確認できる

### 環境

* Windows 7
* curlインストール済(動作確認に使用)

## やりかた

### NodeJSをインストールする

[公式サイト](https://nodejs.org/ja/)からインストーラを落としてただインストールするのが一番シンプルです。将来に渡って使いそうでNodeJSのバージョン管理を気にする場合は[Nodist](https://github.com/marcelklehr/nodist/releases)等を経由してインストールする方が吉。自分は↓の記事に従って導入しました。

* nodistでNode.jsをバージョン管理 - Qiita
    + https://qiita.com/satoyan419/items/56e0b5f35912b9374305

### HTTPサーバを書く

モック用のお手軽サーバなので、最低限。
JS初心者なので色々コードが醜いかもしれません。勉強します。

```javascript:app.js
let http = require('http');
let url = require('url');
let querystring = require('querystring');

let myApp = function(request,response){
    let timestamp = new Date();
    let parsedUrl = url.parse(request.url);
    let parsedQuery = querystring.parse(parsedUrl.query);
    let res_body={
        method : request.method,
        path : parsedUrl.pathname,
        query : parsedQuery
    };
    // getパラメータに"delay=xxx"があれば、そのミリ秒だけ遅延させる
    let delay = (parsedQuery.delay ) ? parsedQuery.delay : 0;
    setTimeout((path,res,ts)=>{
        let elapsed = Date.now()- ts.getTime();
        res.writeHead(200,{'Content-Type':'text/json'});
        res.end(JSON.stringify(res_body)+"\n");
        let logStr = `[${ts.toLocaleString()}] "${path}" ${elapsed}`;
        console.log(logStr);
    },delay,parsedUrl.path,response,timestamp);
};

// ローカルの8081番ポートで起動。環境に応じて変更
http.createServer(myApp).listen(8081,'127.0.0.1');
```

### HTTPサーバを起動

上記`app.js`のあるフォルダで以下コマンドを叩きます。

```bash
$ node app.js
```

これだけで準備完了です。`http://localhost:8081/`以下の任意のアクセスに応答し、HTTPメソッドとアクセスしたパス、getパラメータのクエリの中身だけJSONで返してくれるシンプルなサーバが出来上がりました。

getパラメータで`delay=xxx`としてミリ秒数を指定することで、その時間だけレスポンスを遅らせることができます。

#### 実行例 : 1多重
とりあえずcurlで叩いてみる。

```bash:クライアントサイド
$ date +%s;curl "http://localhost:8081/hogehoge?fugafuga=pi
yopiyo&delay=3000";date +%s
1543430095
{"method":"GET","path":"/hogehoge","query":{"fugafuga":"piyopiyo","delay":"3000"}}
1543430099
```

```bash:サーバサイド
$ node app.js
[2018-11-29 03:34:55] "/hogehoge?fugafuga=piyopiyo&delay=3000" 3000
```

だいたい3秒遅れのレスポンスを返してくれます。

#### 実行例 : 高多重
curlで雑に10多重。

```bash:クライアントサイド
$ for i in `seq 1 10`; do curl http://localhost:8081/hoge?delay=`expr $RANDOM % 3000` >/dev/null 2>&1 & done
```

```bash:サーバサイド
[2018-11-29 03:38:05] "/hoge?delay=179" 179
[2018-11-29 03:38:05] "/hoge?delay=277" 283
[2018-11-29 03:38:05] "/hoge?delay=797" 798
[2018-11-29 03:38:05] "/hoge?delay=1896" 1898
[2018-11-29 03:38:05] "/hoge?delay=1484" 1490
[2018-11-29 03:38:05] "/hoge?delay=1311" 1313
[2018-11-29 03:38:05] "/hoge?delay=1253" 1254
[2018-11-29 03:38:05] "/hoge?delay=1251" 1255
[2018-11-29 03:38:05] "/hoge?delay=2597" 2598
[2018-11-29 03:38:05] "/hoge?delay=2710" 2714
```

多重でもちゃんと叩けますね。

## おわりに

以上、簡単にですがローカルで負荷試験ツールを試す用のモックサーバを構築できました。
でも普通に[WireMockの遅延シミュレート機能](http://wiremock.org/docs/simulating-faults/)つかったほうが早い気がしてきました。
unityでLogicoolSDKを使ってLogitech G29 Steering Wheel（ハンコン）を取得したかった話

`バージョンUnity 2017.3.1f1 (64-bit)`
[unityAssetStore:Logitech Gaming SDK]
(https://assetstore.unity.com/packages/tools/integration/logitech-gaming-sdk-6630)
unityでハンコンを使う場合はこれを使うと早いが、値がとれなかったが解決策がなかったので自分で解決した。
基本的にLogitechSteeringWheel.csを参考にするが、Update()だけ参考にしたら行けるだろうと思っていたがそうではなかった。

#問題点
```cs
void Update()
     {
        if (LogitechGSDK.LogiUpdate() && LogitechGSDK.LogiIsConnected(0))
     }
```
`LogitechGSDK.LogiUpdate()`が`false`になる場合があるからだ

#解決策
```cs
void Start()
    {
       LogitechGSDK.LogiSteeringInitialize(false);
    }
```
`LogitechGSDK.LogiUpdate()`は事前に` LogitechGSDK.LogiSteeringInitialize(false)`の関数を使わないとtrueにならないのだ

#原因
- LogitechSteeringWheel.cs内では `Debug.Log`でこの関数を使っていたので見落とした。
- LogitechSteeringWheel.csを一度動かすと`LogitechGSDK.LogiSteeringInitialize()`がキャッシュされて`LogitechGSDK.LogiSteeringInitialize()`をしてなくても`LogitechGSDK.LogiUpdate()`がtrueになってしまう。
- unityのLogicoolSDKのLogitechSteeringWheelの記事がまったくなかった為。

#最後に
下の記事では実践的なソースコードを載せているので是非参考にして頂きたい。
[LogicoolSDKを使ったハンドル入力](https://shin-go.hatenablog.com/entry/logitech)
ここまで見てくれありがとうございます。
GitHubのREADMEにGyazoでアップロードしたGifアニメーションを簡単に表示する方法。（URLのみでOK）

どうも小太りな鳩です。

最近、AfterEffectスクリプトを作っているのですが、このスクリプトがどういう機能を持っているかという説明をGifアニメーションを使って説明したくなりました。

調べた所、wikiを使ったりissueを使ったりするものがあったのですが、パッと作ってサクッとwiki作りたいときに面倒だなぁと感じたので別の方法探しました。

#この書き方で表示できる
結論から言うと
`![demo](https://gyazo.com/xxxxxxxxxxxxx/raw)`

※xxxxxxxxxxxxxは個別のURL

# サンプルプロジェクト
https://github.com/Kobutori/AEScript/tree/master/999_TextReComp


#なぜ思いついたか

前回の記事　[アウトプットにBacklogを使ってナレッジをためていけば捗るんじゃね？](https://qiita.com/Kobutorina_hato/items/4b8044ed130152565dca)　を書いているときに

> GyazoであればWikiなどにもそのまま読み込むことが可能。

って書いているのを思い出しました。
**Backlogのwikiでも行けるってことはGitHubのwikiでも行けるやろ**


#Qiitaでも行ける
![demo](https://gyazo.com/d64ff7cb56cc139d5315070508302fcc/raw)


とても簡単！説明しやすい！！！
Unity コンポーネントがDestroyされても、オブジェクトがGCで回収されないかもしれない話

# はじめに

まずはこちらの [Unityのnullはnullじゃないかもしれない](https://qiita.com/satanabe1@github/items/e896303859be5d42c188) を読んでから、この記事をお読みください。

# 起きる現象

「コンポーネントが別のコンポーネントを参照しており、その参照先のコンポーネントがDestroy()されたときにリークが発生する可能性がある。」

# どういうこと？

## 下準備

例えば適当なクラスがあったとして

```cs
public class Apple
{
}
```

このオブジェクトをフィールドに持つコンポーネント（被参照側）があり

```cs
using UnityEngine;

public class DeathObject : MonoBehaviour
{
    /// <summary>
    /// Appleはこのコンポーネントに紐づく適当なオブジェクトのつもり
    /// </summary>
    private Apple Apple = new Apple();

    void Start()
    {
        Destroy(gameObject, 3.0f); //3秒後にGameObjectを削除
    }

    void OnDestroy()
    {
        Debug.Log("OnDestroy");
    }
}
```

このコンポーネントをフィールドに持つコンポーネントがあったとする。

```cs
using UnityEngine;

/// <summary>
/// おくりびと
/// </summary>
public class Okuribito : MonoBehaviour
{
    /// <summary>
    /// DeathObjectをフィールドに持つ
    /// </summary>
    [SerializeField] private DeathObject _deathObject;
}
```

## 挙動

`DeathObject`がDestroy()されても、`Apple`のインスタンスが残り続けてしまう。


## なぜ？

まず、クラスの参照関係はこうなります。

```
Okuribito　→　DeathObject →　Apple
```

ここで`DeathObject`がDestroyされるとどうなるかですが、`DeathObject`は**見かけ上はnull**になります。

ですが、`Okuribito`が`DeathObject`を参照したままなので、参照カウントは残っている状態になります。
つまりガベージコレクタ的には`DeathObject`はまだ生きている判定になります。
そのため、`DeathObject`に対して**アクセスするとnullを返すのに、実はインスタンスへの参照は残っている**という状況になってしまいます。

```
Okuribito　→　DeathObject(Destroyはしたけどインスタンスは残ってる) →　Apple
```

すなわち、**`Apple`がリークした原因は`DeathObject`もリークしているから**です。
`Okuribito`がDestroyされない限り、`DeathObject`が解放されず、連動して`Apple`も解放されない、という状態になってしまいます。

# これ問題になるの？

結局は`Okuribito`がDestroyされたら、次のGCで全部まとめて回収されることになります。
なので実際はリークにはなりません。

ただ「次のGCで回収されるだろうな」と思っていたオブジェクトがシーン遷移のタイミングまでメモリに積まれぱなしだった、ということは起きるかも。

# 対処療法

気になるなら、`OnDestroy()`時にフィールドで持っているオブジェクトへの参照を外してあげればいいと思います。
対象へ参照している部分をnullで上書きしてあげればOKです。

ただ、null代入するよりかは、`IDisposable.Dispose()`を呼び出すとかそっちの方が重要だと思います。**というかDispose()は使い終わったら必ず呼べ。**

あとは、フィールドに`IEnumerable<T>`を持っていたりした場合は、そこに入ってるオブジェクトもずっと保持されたまま残ってしまいます。こういったものは明示的にnullを代入するなり、Listなら`Clear()`するなりした方が良いです。

```cs
using UnityEngine;

public class DeathObject : MonoBehaviour
{
    /// <summary>
    /// Appleはこのコンポーネントに紐づく適当なオブジェクトのつもり
    /// </summary>
    private Apple Apple = new Apple();

    void Start()
    {
        Destroy(gameObject, 3.0f); //3秒後にGameObjectを削除
    }

    void OnDestroy()
    {
        Apple = null; // Destroyのタイミングで参照を外す
    }
}
```


# 所感

`Destroy()`したからといって、リソースの解放がただちに完了するわけではないという点に注意しないとダメそう。
Excel2013のVBEで日本語文字化け、日本語入力できない

# Summary
Excel2013 VBEで
文字化けする
日本語入力できない

## Environment
![Screen Shot 2018-11-29 at 2.50.29.png](https://qiita-image-store.s3.amazonaws.com/0/149269/7c7beb9b-5712-3940-a850-511cb72f55fa.png)

## 症状

![Screen Shot 2018-11-29 at 2.04.38.png](https://qiita-image-store.s3.amazonaws.com/0/149269/9e37721e-b225-377c-a0ae-f5093c7b9aac.png)

## 対策

システムロケールを変更

```
ベータ:ワールドワイド言語サポートで UnicodeUTF-8を使用(U)
にはチェックをつけてはダメ
つけると日本語入力、日本語検索ができない
```

![Screen Shot 2018-11-29 at 2.41.16.png](https://qiita-image-store.s3.amazonaws.com/0/149269/80ea075e-61c3-964b-a082-63ae8b55ce81.png)

## 結果
![Screen Shot 2018-11-29 at 2.40.48.png](https://qiita-image-store.s3.amazonaws.com/0/149269/830ec603-f73e-60f7-92ff-87bca83290b3.png)


## 参考

[ExcelのVBA開発画面が文字化けしているとき](http://itemy.net/?p=1839 )
ScrapyでNo module named win32apiエラーの解決策

## 環境
* Windows 8
* python  3.6.3
* scrapy  1.5.1

## エラーについて
[Scrapyのチュートリアル](https://docs.scrapy.org/en/latest/intro/tutorial.html)に沿って進めてたら`scrapy crawl quotes`コマンド実行時に表題のエラーになりました。

## 解決策
```
pip install pywin32
```

## おわりに
解決策がシンプルすぎて何でわざわざ記事書いた？って感じですが、(2018/11時点で）[このエラーに関する日本語記事が１つ](https://blog.mudatobunka.org/entry/2016/08/28/144711)しかなく、そちらだと（環境の問題だと思いますが）「pipが出来なかった」と書いてあったので自分もpip使わずに頑張ろうとしてしまってハマってしまったので、念のため。

ちなみに[win32apiのGithub](https://github.com/mhammond/pywin32)によるとまだpipでのインストールは実験的なものみたいなので失敗したら大人しくバイナリファイルを利用しましょう。

ではでは
git diff でバイナリをテキスト化して差分をとる方法

#TL;DR

``` :console
$ git config diff.binaryfile.textconv dir
$ echo "*.bin diff=binaryfile" >> .gitattributes
```

# textconvに与えるコマンド

|||    
|:--|:--|
|第一引数|にテキスト化したいバイナリのファイルパス|
|標準出力|にテキスト化された結果|

となるようなコマンド。

そもそもバイナリファイルは大きくなりがちなので、全体的に XML とかにシリアライズするととんでもない長さの結果が出てくる。ある程度の構造単位でハッシュをとっていくようなプログラムが良さそうな気がする。

ちなみに、Windowsの`dir`コマンドはファイルを渡すと最重更新日時を含むテキストを返してくれるので、編集していると差分が出ます。（これだけでは役に立ちませんが）

# 問題点

* ```git diff``` でのみ使われる。（Github ページや、 VSCode の GitHistory では見られない）

* ```git diff``` の際に一時的にコンバートされるにすぎないので、コミットごとに差分が取られるわけではない。もちろんマージもできない。

# 参考

[8.2 Git のカスタマイズ - Git の属性](https://git-scm.com/book/ja/v1/Git-%E3%81%AE%E3%82%AB%E3%82%B9%E3%82%BF%E3%83%9E%E3%82%A4%E3%82%BA-Git-%E3%81%AE%E5%B1%9E%E6%80%A7)
備忘録メモ：Raspbianを入れたらすることリスト

#執筆時の環境
Raspbianをインストールした直後に行う作業を備忘録として記載する。
対象としている環境は下記の通り。

|項目 | 内容 |
|:-:|:-:|
|  H/W |  RaspberryPi 3B/3B+ |
|  対象OS | Raspbian GNU/Linux 9 (stretch)  |
|  起動デバイス | USB-SSD/USB-HDD  |
| 使用用途 | 家サーバ |

##補足
SDカードやUSBメモリでの常時稼働はリスク低減の設定はあるにせよ壊れやすいため、見た目はシンプルではないがUSB-HDDやUSB-SSDを利用している。また、基盤ICと接触するタイプのアルミケースにして、さらにケースに大きめのヒートシンクをつけることでファンレス稼働にしている。

# 1. RaspberryPi 3Bの場合は、USBブートを有効にする。(USBブートができない場合の作業)
**(注意) この作業を実施するとそのRaspberryPiは元に戻せなくなる。ブートデバイスを明示的に指定することはできないので、SDカードとUSBメモリが混在している環境では注意が必要になる。**
raspbianがインストールされたSDカードを準備した後、`/boot/config.txt`に以下の行を追加してリブートする。

```/boot/config.txt
(以下の行を追加する)
program_usb_boot_mode=1
```

以上でH/WのファームにUSBブートが有効になる設定になる。作業後は、raspbianがインストールされたUSBストレージ(USBメモリ/USB-HDD/USB-SSD等)で起動する。

## 参考記事

- [How to boot from a USB Mass Storage Device on a Raspberry Pi 3](https://www.raspberrypi.org/documentation/hardware/raspberrypi/bootmodes/msd.md)

# 2. HDMIモードを変更する。(HDMI接続がなくてもHDMI出力をオフにしない設定)
デフォルトの動作では、raspbian起動時にHDMIの接続有無を確認しHDMIモードが決定されるため、仮に起動時にHDMI接続がない場合は、その後HDMIを接続しても認識をしてくれない。

そこで、ごくごく標準的なテレビやディスプレイを想定し、1080p 60Hz決め打ちにすることで、HDMI接続がない(ヘッドレス運用)を可能にする。緊急時には、HDMI接続することでコンソールにアクセスすることができる。

```
$ sudo vi /boot/config.txt
```

```/boot/config.txt
(以下3行を追加、もしくは、コメントアウトを外して修正する)
hdmi_force_hotplug=1
hdmi_group=1
hdmi_mode=16
```

その後リブートする。

## 参考記事
- [Video options in config.txt](https://www.raspberrypi.org/documentation/configuration/config-txt/video.md)

# 3. 稼働確認のために電源LED(赤いLED)をheartbeatにする。
電源オフが完了したか、フリーズしたかどうかの目視確認のために、電源LEDを1秒程度で点滅させる設定。点滅していれば、OSが稼働していることになる。

```
$ sudo vi /boot/config.txt
```

```/boot/config.txt
(以下2行を追加)
# turn power LED into heartbeat
dtparam=pwr_led_trigger=heartbeat
```
その後リブートする。

## 参考記事

# 4. (非推奨設定) root パスワードを設定する。
完全な個人用途だから許されるのであって、商用ではおススメしないが、sudoコマンドによる作業が煩雑なので、常にrootユーザで作業してしまうという古い人間のやってはいけない設定。

```
$ sudo su
# passwd
(パスワードを入力し設定する)

※以降
$ su
#
(以降rootユーザなのでsudo不要)
```

## 参考記事
GeForce RTX 20 シリーズを載せたUbuntu 16.04にCUDA 9.2をインストール

<!---
    Title: GeForce RTX 20 シリーズを載せたUbuntu 16.04にCUDA 9.2をインストール
--->


# はじめに
2018年11月現在、PyTorchが正式にCUDA 10.0に対応していないため、CUDA 9.2をUbuntu 16.04にインストールする。このときに、NVIDIA GeForce RTX 20シリーズを載せていると問題が起きたため、解決方法を記載。

## 症状
NVIDIA GeForce RTX 20シリーズではDriver 410以降が必要。しかし、Driver 410をインストールしたあとに、CUDA 9.2をインストールすると強制的にDriver 396に下げられる。Driver 396ではGeForce RTX 20シリーズに対応していないため、ログインループに陥ってしまう。

## 環境
- Ubuntu 16.04.5 LTS (Xenial Xerus)
- NVIDIA GeForce RTX 2070
- Bash 4.3.48


# 解決手順
## 大まかな流れ
1. Driverをインストールせずに、CUDA 9.2をインストール

1. CUDAと同時に自動的にインストールされたDriverを削除

1. PPAからDriver 410をインストール

## 詳細な手順
### 1. はじめはNVIDIA Driverはインストールしない。
もし、インストールしている場合は以下のようにして、削除する。

```sh:terminal
$ sudo apt --purge remove nvidia-*  # Driverの削除
$ sudo apt --purge remove cuda-*  # CUDAの削除
$ sudo apt autoremove  # 不要になったファイルの削除
```
また、ログインループに陥っているときは**ctrl + alt + F1**でCUIでログインしてから、上記のコマンドを実行する。
**ctrl + alt + F7**でGUIに戻れる。

### 2. CUDA 9.2をダウンロード
CUDA 9.2を下記サイトからダウンロード
<https://developer.nvidia.com/cuda-92-download-archive>
このとき、Installer Typeは「**deb(local)**」を選択。

### 3. CUDA 9.2をインストール
(例)

```sh:terminal
$ cd ~/Downloads
$ sudo dpkg -i cuda-repo-ubuntu1604-9-2-local_9.2.148-1_amd64.deb
$ sudo apt-key add /var/cuda-repo-9-2-local/7fa2af80.pub
$ sudo apt update
$ sudo apt install cuda
```

### 4. CUDAインストールと同時に自動的にインストールされたDriverを削除

```sh:terminal
$ dpkg -l | grep nvidia-*  # これでインストール済みのパッケージが表示される。
$ sudo apt --purge remove nvidia-*  # Driverの削除
$ dpkg -l | grep nvidia-*  # これで何も表示されなければ削除成功
```

### 5. CUDAのパスを設定
`.bashrc`などに以下を追記

```sh:.bashrcなどに追記
# CUDA
export PATH=/usr/local/cuda-9.2/bin:${PATH}
export LD_LIBRARY_PATH=/usr/local/cuda-9.2/lib64:${LD_LIBRARY_PATH}
```

### 6. PPAの追加
```sh:terminal
$ sudo add-apt-repository ppa:graphics-drivers/ppa
$ sudo apt update
```

### 7. Driver 410のインストール
```sh:terminal
$ sudo apt install nvidia-410
```

### 8. **再起動**
```sh:terminal
$ reboot
```
TouchDesignerで外部pythonのライブラリを参照する時には3.5系を指定する

(本記事の情報は古いです。)
2020年4月現在、Touch Designer 2020-official-updateでは、Python 3.7.2がTouchDesigner内部で使用されているバージョンです。



#TL;DR
TouchDesignerのPython 64-bit Module Pathに指定するPythonの site-packages フォルダは、TouchDesigner内臓pythonのversionと同じ3.5系だと動く。


# 環境
- TouchDesigner 0.99 2018.26750
- Windows, macOS
- pythonはpyenvで複数入れてあった。

# 背景と解決策

http://satoruhiga.com/post/extending-touchdesigner/
この記事の「外部のPythonモジュールを使う」のセクションで紹介されている外部pythonをtouchdesigner内部から使用する際に、パス等はあっているはずなのに、import (モジュール名)で読み込めない。
> なお、上記の記事にもきちんと3.5.x系をインストールしましょうと書いてあります。

TouchDesigner内部で使用されているpythonは、3.5.1のようです。これはTextportを見るとわかります。

``` python 
Python 3.5.1+ (default, Apr 22 2016, 18:19:55) 
```

よって外部pythonも3.5系の環境を指定することで外部モジュールを読み込めるようです。


#site-packagesパスの調べ方 
ちなみに、pythonで

```python
import numpy
print(numpy)
-----
<module 'numpy' from '/Users/username/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages/numpy/__init__.py'>
```

のように、site-packagesのフォルダ名を調べることができるので便利。



## path設定後の設定反映のタイミング

### TouchDesignerのPython 64-bit Module Pathに指定する場合

環境を変えた後にはTouchDesigner再起動しないとpythonパスの設定が更新されない挙動でした。

### python上でモジュール探索パスの設定をする場合

```python
import sys, os

#ここのpathは、環境によります。
path = '/Users/username/.pyenv/versions/anaconda3-2.5.0/lib/python3.5/site-packages'

if not path in sys.path:
	sys.path.append(path)
	print('Append new module search path:', path)
```


##### モジュール探索パスが複数設定されてしまう場合に注意

上記の、「python上でモジュール探索パスの設定をする」はsys.pathに、探索させるパスを追加しています。よって、試行錯誤を行なった場合、追加したパスが残っている場合があります。仮に、3.6系へのパスが残っていると、そちらのモジュールを読みに行って、結果モジュールが正しく読み込まれない事が起きます。

こちらも、TouchDesignerを再起動すると、初期化されるので治ります。
[AWS]SNSおよびメッセージ配信サービスについて調べたこと

# はじめに
Amazon SNSについてちょっと調べていた時に、そもそも「メッセージ」ってちゃんと理解してないなと思ったので少し基本的なところからお勉強。

（Amazon SNSについて）
https://aws.amazon.com/jp/sns/
https://docs.aws.amazon.com/ja_jp/sns/latest/dg/welcome.html

# メッセージング、キューイングについて
差し当たり、IBMのknowledge centerに記載がありました。
（もしかしたらWMQ固有の内容もあるかもしれませんが、それは今後の宿題）

（メッセージ・キューイングの概要）
https://www.ibm.com/support/knowledgecenter/ja/SSFKSJ_8.0.0/com.ibm.mq.pro.doc/q002620_.htm
メッセージングとキューイングは、定義としては知っていたものの、言葉としては使い分けできていませんでした。

|名称|機能|
|:--|:--|
|メッセージング|プログラムは、相互に直接呼び出すのではなく、メッセージ形式で相互にデータをやりとりすることによって通信を行います。|
|キューイング|プログラムが異なるスピードおよび時間、異なる場所で、相互に論理的な結合をせずに独立した形で実行できるように、メッセージがストレージ内のキューに入れられます。|

通信の度に毎回セッションを張って対向システムと同期して、などとやっていると通信も遅くなりますし、相手が死んでたら通信できないとなって無駄な待ちが発生してしまうので、そうならないように非同期でやりましょう、というのが目的。

そしてキューにも「Point-to-Point」と「パブリッシュ/サブスクライブ」があり、Amazon SNSは後者に該当する（と思われる。あとでちゃんと確認）

（こちらも後で読む）
https://www.ibm.com/support/knowledgecenter/ja/SSFKSJ_8.0.0/com.ibm.mq.pro.doc/q004870_.htm

肝心のメッセージについては、今日はもう遅いのでまた明日以降にでも。
（一応見つけたページ。正直よくわからない）
https://www.ibm.com/support/knowledgecenter/ja/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q022860_.htm

# 雑記
現在開催中のre:Invent2018の中で、人工衛星のサービスが発表されたと聞いて、「何じゃそりゃ」と思いました。どのように使うのかはあまりピンときていませんが。

https://aws.amazon.com/jp/blogs/news/reinvent2018-aws-ground-station/
https://gigazine.net/news/20181128-aws-ground-station/
tanとarctanが取りうる値の差異によるミス

# 悩んだこと　

タンジェント（以降tan）の逆関数にアークタンジェント（以降arctan）がある
[逆関数](https://mathtrain.jp/inverse)の定義から以下が成り立つと考えていた

```py
import math
theta = math.pi / 4
theta == math.atan(math.tan(theta)) # True
```

実際に上スクリプトの3行目はTrueになる
しかし、以下の場合は3行目はFalseとなる

```py
import math
theta = (math.pi * 3) / 4
theta == math.atan(math.tan(theta)) # False
```
これでしばらく悩んでいた

# 原因
原因を説明するためtanおよびarctanのグラフを以下に描く
なおスクリプトを短くするためにmath.tanおよびmath.atanの代わりにnumpy.tanとnumpy.arctanを使用する

## tanのグラフ

tanのグラフは次のようになる

```py
import numpy as np
import matplotlib.pyplot as plt
from math import pi

x = np.arange(-2*pi, 2*pi, 0.1)
y = np.tan(x)

plt.xlim(-2*pi, 2*pi)
plt.ylim(-4, 4)

plt.xticks([-2*pi,-pi,0,pi,2*pi],["-2pi","-pi","0","pi","2pi"])
plt.yticks([-4,-2,0,2,4],["-4","-2","0","2","4"])

plt.grid(True)
plt.scatter(x, y, s=5)
plt.show()
```
![tan.png](https://qiita-image-store.s3.amazonaws.com/0/99396/4a85e05a-1122-c5dc-c739-bb0221e6aaac.png)


## arctanのグラフ

続いてarctanのグラフを描く

```py
import numpy as np
import matplotlib.pyplot as plt 
from math import pi

x = np.arange(-10, 10, 0.1)                                                                                                                                                                                                                                                                                       
y = np.arctan(x)

plt.xlim(-4, 4) 
plt.ylim(-2*pi, 2*pi)

plt.xticks([-4,-2,0,2,4],["-4","-2","0","2","4"])
plt.yticks([-2*pi,-pi,0,pi,2*pi],["-2pi","-pi","0","pi","2pi"])

plt.grid(True)
plt.scatter(x, y, s=5)
plt.show()
```
![atan.png](https://qiita-image-store.s3.amazonaws.com/0/99396/10913615-f55a-4863-80e8-0e0fecefa348.png)

## 比較

tanとarctanのグラフを比較する
tanのグラフは逆S字状の曲線が繰り返し描画されている
対してarctanのグラフは一つのS字状の曲線が描画されている
そしてarctanが取りうる値は $-\pi/2$ から $\pi/2$ の範囲に限定されることがわかる
その条件を無視して $(3\pi)/4$ $(>\pi/2)$ の値をarctanが出力することを期待してしまったのが私の間違いだった

# 得たこと
値が取りうる範囲を意識する必要があることを学んだ
【備忘録】RDBを使用してRailsでマイグレする方法

[【備忘録】MongoDB使用してRailsでマイグレする方法](https://qiita.com/giosc103/private/65442bf1ac51460004e1)
の続き

MySQL等、RDBでカラム追加等したときの
Rails側のマイグレーション方法の備忘録。

例:
テーブル:Userに
カラム:emailを追加


Model
---

```:cmd
rails generate migration クラス名
```

を叩くことで/db/migrate/
内に下記のようなマイグレーションスクリプトファイルが作成される

```rb
class AddColumnTitles < ActiveRecord::Migration
  def up
  end

  def down
  end
end
``` 

追加:`add_collum :テーブル名,:カラム名,:型`
削除:`remove_collum :テーブル名,:カラム名,:型`
を以下のような感じで

  
```rb
class AddColumnTitles < ActiveRecord::Migration
  def up
    # (カラム追加の場合)
    add_column :Users, :email, :string
  end

  def down
    # (カラム削除の場合)
    remove_column :Users, :email, :string
  end
end
```


で追加し、最後に

```:cmd
rake db:migrate
```

を叩く

それによりcontroller側やviewで追加したカラムを使用できる

使用例
コントローラ

```rb
@user = User.find_by(email: params[:email])
```


view

```erb
<input class="" name = "email" value="<%= @user.email %>">
```
VoyagerのUsersをCSVからseederを使って一括インポート

#Voyagerで大量のユーザーを登録したい

ユーザーメンバーのリストCSVがあるのでそれを一括で読み込んでユーザー登録をしたい。

#Seederをつくる前に

`config/app.php`でタイムゾーンとロケールの設定が正しくされていることを確認してください。

```php:config/app.php
return [
    // ...
 
    'timezone' => 'Asia/Tokyo',
    'locale' => 'ja',
```
#Seederの原型

```path:UsersTableSeeder.php
...\database\seeds\UsersTableSeeder.php
```
上記コピー、編集してCSV取り込むための`VoyagerUsersTableSeeder.php`を作っています

#Seeder保存先

```path:VoyagerUsersTableSeeder.php
...\database\seeds\VoyagerUsersTableSeeder.php
```
#Seederのコード

```php:VoyagerUsersTableSeeder.php

<?php

use Illuminate\Database\Seeder;
use TCG\Voyager\Models\Role;
use TCG\Voyager\Models\User;
use Carbon\Carbon;　//追加

class TkusersTableSeeder extends Seeder
{
    /**
     * Auto generated seed file.
     *
     * @return void
     */
    public function run()
    {

　　　　//追記ここから　　　

        $file = new SplFileObject('database/csv/users.csv');
        $file->setFlags(
            \SplFileObject::READ_CSV |
            \SplFileObject::READ_AHEAD |
            \SplFileObject::SKIP_EMPTY |
            \SplFileObject::DROP_NEW_LINE
        );
        $list = [];
        $now = Carbon::now();
        foreach($file as $line) {
            $list[] = [
                'name'           => $line[0],
                'email'          => $line[1],
                'password'       => bcrypt($line[2]),
                'remember_token' => str_random(60),
                'role_id'        => 2,
                'created_at'     => $now,
                'updated_at'     => $now,

            ];
        }

        DB::table("users")->insert($list);

　　　　//追記ここまで

    }
}

```

#CSV(users.csv)ファイル保存先

```path:users.csv
...\database\csv\users.csv
```

※**csvはutf-8の文字コードのカンマ区切りで保存してください。じゃないと日本語読み込んでくれません。**
Excelからでは上記形式で保存できなかったので、メモ帳で開いてutf-8で保存しました。

#CSVの内容

タイトル行はないです。

```csv:users.csv
NAME1,hoge1@hoge.co.jp,password1
NAME2,hoge2@hoge.co.jp,password2
NAME3,hoge3@hoge.co.jp,password3
```

#Seeder実行

```php:artisanでseeder実行
php artisan db:seed --class=VoyagerUsersTableSeeder
```

#参考記事

https://qiita.com/shosho/items/caf535b1df5cb8d8ae92
機械学習のアルゴリズム覚え書き

# はじめに

機械学習を学びたいのですが、基礎から学ばないと落ち着かないので、
アルゴリズムのお勉強します。

# 学習の種類
機械学習の学習には、以下のような種類があります。

* 回帰(Regression)
* 分類(Classification)
* クラスタリング(Clustering)

## 回帰
回帰は、連続するデータのこと。
時系列、例えば特定の企業の成長率や、特定の人物の身長の推移。
連続するデータに関数的な法則性を見いだすことができれば、今後どうなるかなどを予測することができます。

## 分類
分類は、特定の事象を分類に分けること。
例としては、受信したメールが迷惑メールかそうでないか。画像の中の数字が0〜9のいずれか。
分類数が2通りであるものを二値分類、3通り以上のものを多値分類と呼びます。

## クラスタリング
クラスタリングは分類と似ていますが、ラベルがついていません。(正解、不正解という答えのある分類ではないということ）
例としては、特定の居住区内100人の年収データなど。

## 教師あり学習と教師なし学習
機械学習は、膨大なデータを投入することで精度を増していきます。
学習には、答えのある学習（教師あり学習）と、答えのない学習（教師なし学習）があります。
今回紹介した種類でいうと、回帰と分類が教師あり学習。クラスタリングは教師なし学習にあたります。

#　おわりに
とりあえず学習の種類について学びました。今後各学習の深掘りを行っていければと思います。

以上です。お疲れ様でしたー。
Advanced Custom Fields のアドオン Options Page（オプションページ）に acf_add_options_sub_page でエラー


サブページが「このページにアクセスする権限がありません。」というエラーでアクセスできない原因。

acf_add_options_sub_page の menu_title を日本語にしている。

サブページでなければ menu_title に日本語を使用してもエラーは出ない。
SQLアンチパターンを読んで

# １. ジェイウォーク（信号無視）
１つのフィールドにカンマ区切りフォーマットのリストを格納すること。

| システム | 管理者番号 |
|:-:|:-:|
| Aシステム | 1,23,456,7890 |
| Bシステム | 1,2,3,4,5,6 |

このようにを一つのフィールドに複数の値を格納することです。

## 特徴
- メリット
    - 非正規化による高速化
- デメリット
    - 検索におけるパターンマッチが必要
    - 他のテーブルとの結合が困難
    - COUNTなどの集約クエリを使用できない
    - 型のサイズが入力最大数となる
    - リストの一部を特定して更新する必要がある
    - 区切り文字は使用できない
    - 型違いのデータをはじけない

## 対策
テーブル１つ追加して多対多を解消する。
１フィールド１要素で構成できるような設計にすること。
指定したディレクトリのファイルの名前一覧を表示する

##ディレクトリの中にあるファイル名を取得する
勉強用のメモとして書きます。
## 環境
Visual Studio Community 2017

## 方法
GetFilesメソッドでファイルを取得します。
第一引数は指定したディレクトリのパス、第二引数はファイルの条件を指定することができます。

##ソースコード
    public class ReadFiles
    {
        private string filePath;

        public ReadFiles(string path)
        {
            this.filePath = path;
            var files = Directory.GetFiles(path);
            for (int i = 0; i < files.Length; i++)
            {
                Console.WriteLine(files[i]);
            }
        }
    }

これでReadFilesクラスのオブジェクト作る際に引数にディレクトリのパスを指定することで、そのディレクトリ内にある拡張子がtxtのファイル名の一覧を取得することできます。