OmniAICreator/Qiita-1.07M huggingface dataset:
SQL Workbench/J インストールから起動メモ

#OS
ubuntu 16.04

#インストール
[ダウンロードページ](https://www.sql-workbench.eu/downloads.html)より、zipファイルダウンロードし、任意の場所に展開する。

#JREのインストール
JREインストールされていない場合は以下コマンドでインストールする。

```shell:
$ sudo apt-get update
$ sudo apt-get install default-jre 
```

#起動
SQL Workbench/Jを展開したディレクトリに移動し、以下コマンド実行。

```shell:
$ java -jar sqlworkbench.jar
```
以下コネクション画面が出るので、Driver、URL、Username、Passwordを入力する。

![Screenshot from 2018-05-20 17-56-08.png](https://qiita-image-store.s3.amazonaws.com/0/209773/7b119d9e-546a-e00e-bfac-cbe4c8b8d3a1.png)

以下の画面（The library for the driver is not accessible）が出る場合、
YESを選択して、JCBCの場所を指定する。

![Screenshot from 2018-05-20 18-16-32.png](https://qiita-image-store.s3.amazonaws.com/0/209773/4675c1ac-d4e1-a3b4-9202-b10a412eb07e.png)

右側のフォルダマーククリックして、JDBCの場所を指定する。
JDBCがない場合はダウンロードしておく。
PostgreSQLならば[こちら](https://jdbc.postgresql.org/download.html)からダウンロード。

![Screenshot from 2018-05-20 18-20-24.png](https://qiita-image-store.s3.amazonaws.com/0/209773/fbe8d81b-8bea-6c45-bb2c-0323d06c692c.png)


コネクション画面に戻ってOKするとSQL入力画面が起動する。

#ショートカットの設定
Toolメニューの「Configure Shortcuts」から設定できる。
SQL実行はF5でなど。
GitHubのwikiを使ってみよう！

## **はじめに**

OSSやコードの公開先として定番になっているGitHub。利用している方も多いんじゃないでしょうか。
このGitHub内にwikiが作成できる機能に対する作成備忘録となります。

### **wiki利用の個人的経緯**

勉強の為[C言語に合ったデザインパターンの表現](https://qiita.com/developer-kikikaikai/items/8e7858c130c8ae8df488)という形でQiitaに記事を書く
→ライブラリとして割と自分が使いたい形になってきたなー
→よっしゃ！ちゃんとしたOSSっぽくしよう！
→どうせならQiitaの記事じゃなく、GitHubのコード近くにクラス図くらい欲しいよな～

でもリポジトリに入れると無駄にサイズが重くなるし。何か今までの記事を利用して、まとめサイトを作れないかな～
…そういえばGitHubのwikiがあるな、使ってみるか！

という流れです。

ちなみに作成したWikiは[こんな感じ](https://github.com/developer-kikikaikai/design_pattern_for_c/wiki)

## **GitHubとは**

本家ホームページより。

>GitHubは、ユーザのみなさんからヒントを得て作成された開発プラットフォームです。オープンソースプロジェクトやビジネスユースまで、GitHub上にソースコードをホスティングすることで数百万人もの他の開発者と一緒にコードのレビューを行ったり、プロジェクトの管理をしながら、ソフトウェアの開発を行うことができます。

無料で登録できるgitを利用したソース管理の為のウェブツールです。こちら、OSSをソースコードからビルドしたことのある方は必ず1度は見たことがあると思います。そういったオープンソースプロジェクトや個人の趣味まで、gitを使っていい感じに開発しましょう！というウェブツールとなっています。

### **GitHubでは何が出来るの？**

最初の印象以上に色々なことが出来そうなんですよね。

- ソース管理  無料のgitリポジトリとして活躍します。HTTPS/ssh等のセキュリティ認証が充実しているため、これだけでもいい有用なサーバーですね。
- issue作成 ソースコードに対するタスクをissueで管理できます。記憶力の悪い私はこういう見える化機能大好きです。
- **wiki作成**  今回紹介する機能です。今日初めて使ってみたレベルですが、特にQiitaの利用者には非常に使いやすいのではないかと思います。

その他プロジェクト作成など色々なことが出来そうですが、ここでは割愛。

## **Wiki機能**

Wikiは、GitHubのリポジトリ内、Code等のタブ内にあります。
自作リポジトリで表示されてない方は、タブ内のSettings->FeaturesのWikiにチェックを入れれば出てくると思います。

<img width="1000" alt="wiki.png" src="https://qiita-image-store.s3.amazonaws.com/0/252277/2c3207a1-3d18-53b1-8a15-403bbddb0c89.png">

最初はREADMEの拡張くらいなものかなと思っていたのですが、普通にこのリポジトリを説明するための簡易ホームページくらいの機能はありそうです。私的には十分すぎる！

### **形式について**

Wikiを記載するフォーマットは無料版を利用している私でも**9種類から選択可能**です。
何よりもいいのは、**Qiitaと同じMarkdown方式**もサポートしています。

実際記事の説明をそのまま張り付けてもほぼ同じ内容が表示されるくらい。
その他おそらく一般的であろう形式をサポートしているので、他の何かしらのサイトでライブラリのまとめを行っている方も、スムーズに移行できるのではないでしょうか。

### **ページの追加について**

これが好きに出来るのか不安だったのですが、杞憂でした。**普通にページの追加が可能です。**
形式にもよるかもしれませんが、**作成したページへのリンクも可能**なので、非常にまとまった説明サイトとしての機能を果たすことが出来ます。

#### **特殊ページ**

ページの追加は可能なのですが、特殊なページがいくつかあります。
これらは便利なページなのですが、**名前を変えると普通のページ扱いになりそうなので注意**です。

- **Home** --wikiページを開いた際のTopページです。触ってみると、一見タイトルが変えられそうなのですが、Topページとして扱われなくなりました。
- **_Sidebar** --常にwikiの横に表示されるページです。目次として便利に利用出来そうです。
- **_Footer** --常に↓に表示されるページです。自ホームページの宣伝などに使うとよいのではないでしょうか。

### **Markdownで本当にそのまま使えるの？**

Qiitaで出来ることは一通りできるようです。

- サーバー上にある図の張り付け -- Qiitaが利用しているサーバーの図も張り付けられました。
- サイトの参照 -- Qiita同様`[XXX](URL)`で出来ます。
- コードの張り付け -- ```で囲めば出来ます。言語対応もされているようです。

!\[image]\(url)の形式じゃなく、画像ドラッグで出てくる*img XXX *の形式(<と>で括られてるやつ)も使えました。

### **管理方法について**

このwikiの記載情報も、GitHubのどこかのリポジトリで管理されているようです。
[こんな感じで](https://qiita.com/jollyjoester/items/55a863d6b53f8ffd2d48)wikiをcloneして編集している方もいらっしゃいます。

### **サンプル**

作成中のライブラリwikiが[こちら](https://github.com/developer-kikikaikai/design_pattern_for_c/wiki)になります。
基本作っていたREADMEやQiita記事をがりがり張り付けただけですが、wikiがあるだけでそれっぽくなっていきますね。
Qiita側の記事も張れるので、ベースだけ書いて詳しくは日本語を読め！みたいなスタンスのwikiにも出来そうです。

## **参考**

[日本語でのGitHub Wikiの編集ノウハウ](https://github.com/doc-wiki-jp/wiki/wiki/GitHub-Wiki%E3%81%AE%E7%B7%A8%E9%9B%86%E3%83%8E%E3%82%A6%E3%83%8F%E3%82%A6)

[GitHubのWikiに画像を貼付ける際にちょっと迷ったのでメモ。(clone利用の例)](https://qiita.com/jollyjoester/items/55a863d6b53f8ffd2d48)
「試して理解　Linuxのしくみ」のコードをRustに移植してみた話

#「試して理解 Linuxのしくみ」
[Amazon](https://www.amazon.co.jp/dp/477419607X)では "[試して理解]Linuxのしくみ ~実験と図解で学ぶOSとハードウェアの基礎知識" という名前になっています。
[著者の武内さん](https://twitter.com/satoru_takeuchi)のハンドルネームから、sat本と呼ばれることも多い書籍です。

武内さんが配布されているCのコードは[こちら](https://github.com/satoru-takeuchi/linux-in-practice)、私がRustで書き直したコードは[こちら](https://github.com/gyu-don/linux-in-practice)にあります。

以下は、ポエムです。

## 本の感想
私自身は、Linuxやメモリにそれなりには興味を持っていたので、すごく目新しい内容は、それほど多くはありませんでした。けれども、読んで非常によかったと感じています。
「試して理解」と銘打っているとおり、書かれていることを実際に試して、理解を深められるようになっています。なんとなく聞いたことはあったけれど、実際試したことはなかったものを、実際に試すことができたのは本当によかったです。

#なぜRustに移植したのか

1. 持論として、「プログラムをただ動かすより、写経でもいいから自分で書いた方が力がつく」というのがある。けれど、ただの写経だとつまらないので、Rustに移してみた
2. 「Rustって、システムプログラミングに適しているって触れ込みだけど、実際どうなん? ぶっちゃけ、Cよりやりやすいの?」を体験したかった

##やりやすかったのか?

### pros:
- システムコール呼び出し以外の部分について、CよりもRustの方が書きやすいのは(少なくとも私の中では)疑う余地がない
- `nix` というクレートが非常にいい感じのラッパーで、「戻り値が-1じゃないか見て、errno読んで……」とかしなくてもRustのResult型で扱えた([nixのドキュメント](https://docs.rs/nix/latest/nix/))
- ちゃちゃっと`struct`を作って、`Drop`をimplして、ファイルの閉じ忘れがないようにするとか、そういうのができた(ただし、これはCでは難しいがC++ならできる)

### cons:
- ラッパーがなかったり、あんまりいい感じじゃない部分は、自分でがんばって書くことになった
- CのNUL終端文字列は、ヒープを使わずに作るのは大変(ヒープでもよければ`CString::new(...)`でよさそう)
- `nix`の`ioctl`マクロがしんどい。sat本で必要な`BLKSSZGET`を`ioctl`マクロで扱う方法は結局分からず、`libc`の`ioctl`を使った
- `nix`や`libc`などのRustのドキュメントと、Cのドキュメントの両方を参照したくなることが結構あって、二度手間だった
- 型の扱いが厳格で、とくに`void*`を特別視してくれないのでキャストが面倒だった

##結局どうよ?
Rust万歳、で終わらせたかったのですが、やはり、元がCを前提にしたインタフェースである以上、ラッパーに頼らないと便利じゃないし、ラッパーは完全じゃないし、という話になる気がしました。
それでもやっぱり、`Result`でエラー処理できるのは本当に便利だと思うし、ラッパーが気に入らなくても自分でそこまで手間かけずに作れるし、悪くはなさそうな感じです。
WordPressの子テーマからフルパスを取得するなら

ググったところ、 get_stylesheet_directory_uri() を使うように書かれているのを、いくつか目にしたのですが、サーバのルートから指定しないとincludeできないことがあったので、忘れないようにメモしておきます。

```php
get_theme_file_path() // => フルパス（サーバのルート）
get_stylesheet_directory_uri() // => 絶対パス（サーバーの公開領域のルート）
```

#参考
https://wordpress.stackexchange.com/questions/192773/override-get-template-directory-in-child-theme
ベストアンサー（？）のような項目で、`get_stylesheet_directory_uri()`がおすすめされていますが、その下の回答で`get_theme_file_path()`について記載されています。
自分がUbuntuを導入した直後にすること

# はじめに
はじめて記事を書いたので不備などがあった場合、教えていただければ幸いです。
他にやることを思い出したら更新します。

# 環境
自分が試してうまく動作した環境です。
Ubuntu 16.04 LTS
Lubuntu 16.04.4 LTS


# やること
## ホームディレクトリの以下を名前を日本語から英語にする。
```
$ LANG=C xdg-user-dirs-gtk-update
```


## bashの補完で大文字と小文字を区別しないようにする。

~/.inputrc というファイルに以下を記述した後保存する。

```
set completion-ignore-case on
```


## CapsLockキーをCtrlキーとする。
```。
$ sudo vim /etc/default/keyboard
```

で設定ファイルを開き

```
XKBOPTIONS="ctrl:nocaps"
```
と変更して保存する。


## 無変換キーで英語、変換キーで日本語を入力できるようにする。
・半角/全角キーが少し遠い。
・もともとMacを使用していたため、スペースの左右での切り替えに慣れているため。
1. メニューバーに表示されているキーボードもしくは「あ」のアイコンをクリック
2. 「設定」 -> 「全体の設定」を開く
3. 「拡張オプションの表示」のチェックボックスにチェックを入れる
4. 「入力オプションをオンに」を選択した後、キーボードの変換キーを押して追加する。
5. 同じように「入力オプションをオフに」に無変換キーを割り当てる。

![Screenshot from 2018-06-04 20-37-24.png](https://qiita-image-store.s3.amazonaws.com/0/247877/4873bb7d-94c5-1bde-743a-a5d8d90feb1b.png)


# 参考にしたページ
[Qiitaの簡単な書き方まとめ](https://qiita.com/hkengo/items/46103d5c595d468f3c82)
[Ubuntuでホームディレクトリの中身を英語にする](https://qiita.com/taiko19xx/items/d1a001bfc25245b91354)
[bashの補完で大文字小文字を無視する](https://qiita.com/shoma2da/items/2ecf5a28934dae97dfe8)
[Ubuntu 16.04 CapsLockをControlに置換する方法](https://qiita.com/hirooooooaki/items/f404e76c6f171769412a)
Visual Studio 2017でlibtorrentのdllを使ってBitTorrentクライアントをビルドしてみた (2019年版)

# 使ったもの
- Visual Studio 2017 Community Edition
- libtorrent 最新版
- Boost 1.69.0 (https://dl.bintray.com/boostorg/release/1.69.0/source)

# やったこと
## Boost 1.69.0の準備
1. ダウンロードしたソースを展開
2. Windowsの環境変数設定から、ユーザー環境変数BOOST_ROOTに展開先ディレクトリを設定。BOOST_BUILD_PATHに展開先ディレクトリを設定。Pathに展開先ディレクトリを追加。
3. VS 2017用 x64 Native Toolsコマンドプロンプト(スタートメニューから起動できる)を起動し展開先ディレクトリに移動
4. 展開先ディレクトリにあるbootstrap.batを実行してビルドツールb2.exeを作成(b2.exeは展開先ディレクトリにできているので、パスを通しておく。後でもう一度使う)
5. b2 msvc -j4でビルド実行(これでdebug版ができる)
6. 準備完了

## libtorrent 1.1.7のビルド(標準の方法)

こちら https://www.libtorrent.org/building.html を参考に、libtorrent.libをビルドしていく。
1. git clone https://github.com/arvidn/libtorrent.gitで最新版ソースをダウンロード
2. Windowsの環境変数設定から、ユーザー環境変数LIBTORRENTに展開先ディレクトリを設定
3. VS 2017用 x64 Native Toolsコマンドプロンプト(スタートメニューから起動できる)を起動し展開先ディレクトリに移動
4. b2.exe msvc link=shared runtime-link=shared dht=on extension=on -j4でビルド実行。torrent.dllとtorrent.dllはbinディレクトリ以下に生成される
5. 準備完了

## libtorrent付属のclient_testのビルドと実行

client_testはCUIベースのtorrentクライアント。きちんとライブラリがビルドできているかの確認に使うことができる。

1. Visual Studio 2017のファイル > 新規作成 > プロジェクトから Visual C++ > Windowsデスクトップ > Windowsコンソールアプリケーション を選択して新規プロジェクト作成(仮にclient_testというプロジェクト名とする)
2. デフォルトで含まれているclient_test.cpp, stdafx.cpp, stdafx.h, targetver.hをすべてプロジェクトから削除し、ファイル本体も削除
2. libtorrent 1.1.7の展開先ディレクトリのexampleディレクトリ以下にある`client_test.cpp print.cpp session_view.cpp torrent_view.cpp print.hpp session_view.hpp torrent_view.hpp`をプロジェクトに追加
3. プロジェクト>(プロジェクト名)のプロパティについて以下の設定を行う
    - 構成をDebug、プラットフォームをx64に設定(以降の設定を構成Releaseについても繰り返す) 
    - C/C++ > 追加のインクルードディレクトリに\$(BOOST_ROOT)と\$(LIBTORRENT)\includeを追加
    - C/C++ > プリプロセッサ > プリプロセッサの定義にをいくつか定義を加える。この定義をlibtorrentをビルドした時と同じものにしないと、ビルドエラーが出てしまうので注意。
        - この定義は、libtorrentのビルドディレクトリに行き `b2.exe msvc --debug-building`で表示される`<define>`後の定義を全て抜き出すことで得られる。
        - 今回は`TORRENT_USE_I2P=1 _WIN32_WINNT=0x0600 BOOST_ALL_NO_LIB BOOST_ASIO_ENABLE_CANCELIO BOOST_ASIO_HAS_STD_CHRONO BOOST_MULTI_INDEX_DISABLE_SERIALIZATION BOOST_SYSTEM_DYN_LINK=1 BOOST_SYSTEM_NO_DEPRECATED TORRENT_LINKING_SHARED WIN32 WIN32_LEAN_AND_MEAN _CRT_SECURE_NO_DEPRECATE _FILE_OFFSET_BITS=64 _SCL_SECURE_NO_DEPRECATE _WIN32 __USE_W32_SOCKETS`を設定(もとからあったものを上書きした)
    - C/C++ > プリコンパイル済みヘッダ でプリコンパイル済みヘッダーを使用しないに設定
    - リンカー > 追加のライブラリディレクトリに先程ビルドしたtorrent.libがあるディレクトリを指定
    - リンカー > 入力 の追加の依存ファイルにtorrent.libを追加
    - torrent.dllをプロジェクトファイルのあるディレクトリにコピー
4. Visual Studio画面の上部でDebug x86構成を選択してビルドを行うと、所望のexeファイルがソリューションディレクトリ以下のDebugディレクトリ内に生成された
5. Ubuntuの配布用torrentファイルをダウンロードし、プロジェクトディレクトリ内に保存
6. VS2017のデバッグ > コマンドライン引数にtorrentファイル名を設定。(ここではubuntu-16.04.5-desktop-amd64.iso.torrent)
7. VS2017からデバッグ実行を行い、ファイルダウンロードが行われることを確認した
    - 注意点は、ポート6881から6889が開放されていないとlibtorrentはPort Control Protocol v2を使ってポートマッピングをしようとするが、ルーターがそれに対応していないと動作がそこで止まってしまう。WireSharkなどで動作確認しながら実験するのがおすすめ。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/75235/4fc4a981-8b7e-e8a9-01d4-b2f2600ec2b1.png)
ChoreonoidのSimpleControllerを使ってみる

前回はchoreoniodのプラグインを作成してみました。前回のものだとシミュレーションを回していない状態で、関節に力が入っていない状態であるためシミュレーションを実行するとその場で崩れ落ちてしまいます。今回はSimpleControllerを用いてPD制御を実装し、実際にシミュレーションを回して直立させて見ようと思います。

## 環境
OS: ubuntu 16.04 LTS
version: choreonoid-1.7.0

## サンプルコード
```cpp
#ifndef _PDCONTROLLER_
#define _PDCONTROLLER_

#include <iostream>
#include <string>
#include <cnoid/SimpleController>
#include <cnoid/Link>

using namespace std;
using namespace cnoid;

class PDController : public cnoid::SimpleController
{
	Body* ioBody;
	vector<double> qref, qold;
	vector<double> pgain, dgain;
	double dt;

public:
	virtual bool initialize(SimpleControllerIO* io) override
	{
		ioBody = io->body();
		dt = io->timeStep();

		for(int i=0; i < ioBody->numJoints(); ++i){
			Link* joint = ioBody->joint(i);
			joint->setActuationMode(Link::JOINT_TORQUE);
			io->enableIO(joint);
			qref.push_back(joint->q());
		}
		qold = qref;

		load_gain(ioBody->numJoints(), pgain, dgain);

		return true;
	}

	void load_gain(size_t numJoints, vector<double> &pgain, vector<double> &dgain)
	{
		FILE *fp;
		double temp_pgain, temp_dgain;
		std::string gain_filepath = "/usr/lib/choreonoid-1.7/simplecontroller/pdgain.txt";
	
		if((fp = fopen(gain_filepath.c_str(),"r")) == NULL)
		{
			std::cerr << "gain file not found." << std::endl;
			return ;
		}

		pgain.clear(); dgain.clear();

		pgain.resize(numJoints);
		dgain.resize(numJoints);

		int i=0;
		while(fscanf(fp,"%lf %lf",&temp_pgain,&temp_dgain) != EOF)
		{
			pgain[i] = temp_pgain;
			dgain[i] = temp_dgain;
			i++;
		}

	}

	virtual bool control() override
	{
		for(int i=0; i < ioBody->numJoints(); ++i){
			Link* joint = ioBody->joint(i);
			double q = joint->q();
			double dq = (q - qold[i]) / dt;
			double u = (qref[i] - q) * pgain[i] + (0.0 - dq) * dgain[i];
			qold[i] = q;
			joint->u() = u;
		}
		return true;
	}
};

#endif
```

このサンプルで行っていることは簡単なPD制御で、外部からPゲイン、Dゲインをファイルで読み込み、トルク制御を行っています(このサンプルではゲインファイルを外部で指定して読み込んでいますが、これはゲインの微調整時にわざわざコンパイルが面倒という理由で外部ファイルで定義していますが、基本そんなに変える値ではないのでコード内に直に定義でも良いと思います)。

SimpleControllerとはchoreonoid向けに設計されたコントローラです。並んでいる関数はプラグインのときと似ていますがロードされた際initializeが一度呼び出され、シミュレーションが実行されるとcontrolがループで呼びだされます。ループ周期はchoreonoid側で設定され、その周期毎にループが走ります。SimpleController内で実行周期を取得する場合はSimpleControllerIOクラスのtimeStep関数を用います。

SimpleControllerは他のプロセスとのやり取りまで提供するわけではなく、簡単なコントローラの実装を目的としています。なので例えばトルク制御だけでなく画像認識やマニピュレーションの経路計画などのモジュールを組み合わせる場合はBodyRTCを用いたほうが良いと思います(OpenRTM向け)。

## まとめ
シミュレーションを回してロボットを立たせることができるようになりました。次は実際にこれを使って簡単に制御っぽいことをしてみますかね。
InterfaceBuilderで出てくるステータスバーの消し方

# 概要
UIViewを配置するとデフォルトで付いてくるステータスバーの消し方
よく忘れるのでメモ書き

# やりかた

InterfaceBuilderの「Simulated Metrics」から「Size」を「Inferred」->「Freedom」に変更

<img width="919" alt="スクリーンショット 2018-05-20 17.43.26.png" src="https://qiita-image-store.s3.amazonaws.com/0/161845/8b0d9e71-8347-34fa-9b1d-b012d6298f57.png">

あとはちょっとInterfeacBuilder上で適当にViewのサイズを変えると再描画されて消える。

<img width="917" alt="スクリーンショット 2018-05-20 17.54.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/161845/a795cbcb-caf9-086d-f5bc-1993b2c02c68.png">
Java Day 2018

少し遅れていますが、木曜日にJava Day 2018を参加したので、その感想をここに記しておきたいと思います。

正午にオフィスビルから出ると、外は抜けるような晴天でした。既に初夏に入ったが、今日は比較的涼しいほうでした。
お昼は同僚の薦めで久しぶりに刀削麺の店に行くことにしました。私はマーラー刀削麺を頼んだが、同僚は麻婆豆腐にしました。
私は中国湖南省（湖南料理は中国で一番辛い料理ともいわれる）の出身とはいえ、辛い物には弱くて、よく友人に「偽湖南人」と言われます。そのため、辛い物を注文すると、いつもドキドキで、今日は食べれるかなと不安に思います。今日は汗をかきながらではあるが、普通にいけました。逆に普段に辛い物に強い同僚のほうが辛すぎで麻婆豆腐を半分食べ残しました。同じマーナー系なのに、なぜそれほど辛さが違うか、一瞬もう「偽湖南人」にはもう言わんぞと思うほどでした。これから参加する「Java Day 2018」もこのマーナー味と同じように熱ければいいですね。

会場のシェラトン都ホテル東京についたら、もう2時過ぎで、2時からのセッションも既に開始されました。Java Dayは何年ぶりの参加ですが、過去に比べ、規模もスポンサー数も縮小している第一印象でした。Oracle社がJDKの開発を手放しして以来、一時期Javaの終焉ではと話題を呼びました。やはりOracle社も昔ほどJavaに精力を掛けなくなるかな。

#Java EE 8 and now Jakarta EE
JAX-RS、JSON、Servlet4.0、HTTP/2、JSF2.3、CDI2.0、BeanValidation2.0などいろいろ紹介されましたが、あんまり新鮮さが多くない感じでした。
製品開発の関係で、JSON Pointer/JSON Patch/JSON Bindingに興味がありましたが、ほかの方の[JSON処理のBenchmark結果](https://github.com/fabienrenaud/java-json-benchmark)では、javax-jsonがさえない結果でした。

そもそもJavaEE8を対応しているApplication Serverはまだかなり少なく、JavaEEもEclipse Foundationに移管されて、「Jakarta EE」という新ブランド名で再スタートとなりますが、これからの道筋がどうなるか気になりますね。

#Java in Serverless Land
**Fn Project**というオープンソースのプロジェクトが紹介されました。
[Fn Project](https://fnproject.io/)のホームページには以下のように記しています。
「The Fn project is an open-source container-native serverless platform that you can run anywhere -- any cloud or on-premise. It’s easy to use, supports every programming language, and is extensible and performant. 」
Fn Projectはサーバレスアーキテクチャをさらに進化させたものと言われるFaaS（Function-as-a-Service）システムを提供する目的で、今後注目しておきたいですね。

#Get ready for a cloud native, service-meshed Java EE
[Kubernetes](https://kubernetes.io/)と[Istio](https://istio.io/)で管理するアプリケーションのメッシュにJava EEをどう融合させるかを紹介されました。
業務システムもどんどんクラウド化される昨今では、Javaも如何にクラウドを対応するか、Javaの将来の発展に関わるもので重要なポイントとなります。

#Performance tuning with poor tools and cheap drink
JPDM（Java Performance Diagrostic Model）を紹介されました。
[VisualVM](https://visualvm.github.io/)などを利用して、JVMの動きを可視化し、アプリケーションのパフォーマンスのボトルネックを特定することやプログラムを改良するテクニックのデモも実施されました。

- synchronizedによる同期化のスコープをなるべく小さくする（当然ですが）
- Collections.synchronizedMapでMapをスレッドセーフにするよりConcurrentHashMapを使う方がパフォーマンスがよい
- HashMapのキーとして、複数の文字列を連結(firstName + familyName)することより、複合キークラスを作成したほうがパフォーマンスがよい

周@ソフトシンク
[ メモ ] php date関数 現在の日付・時間を取得

#phpで現在の日付・時間を取得する関数 「 date( ) 」

フォームの生年月日を入力する部分で、使用したので書いておきます。


```ruby:index.php
$now = date("Y");

echo $now;

2018
```
#オプション
| パラメータ     　　|    説明　    　　　　　|    表示例    |
|:--------------|:-------------|:------------|
| d             | 日 （二桁の数字）　| 01 , 20     |
| D          　　　　　　| 曜日 　　　　　　     　　| Sun , Fri   |
| m           　　　　| 月（二桁の数字）  |04 , 11      |
| Y             | 年（四桁の数字）  | 2018 , 1990 |
| H             | 時（24時間単位）  |07 , 23      |
| i          　　　　　　| 分（二桁の数字）  | 01 , 55     |
| s          　　　　　　| 秒（二桁の数字）  | 03 , 40     |
WordPress のテーマ名を変更する手順


## 事前に必ず理解しておくこと

* 必ずバックアップ (Webサイトデータ、データベース両方) を取った上で作業すること
* テーマ名の文字列がコードやテキスト中で使われている可能性がある場合、この方法は使えない。意図しない箇所が置換されると深刻な状態になるから

## データベース中のテーマ名を変更

シリアライズされたデータも適切に置換するため、[Database Search and Replace Script in PHP](https://interconnectit.com/products/search-and-replace-for-wordpress-databases/) で置換 (Search-Replace-DB-master)。


## ファイル名の置換 (ディレクトリ名、ファイル名)

親子テーマを使ってる場合は、混乱を避けるため続けて行うこと

1. テーマディレクトリそのもの新しいテーマ名にリネーム
2. Finder でそのテーマディレクトリのルートにいる状態で旧テーマ名を検索し出てきたもの(Sublime Text の設定ファイルや、potファイル)を全て新テーマ名にリネーム


## 各ファイル中のテーマ名の置換

エディタで対象のテーマディレクトリを選び、一気に置換。
対象ファイルが大量だと高負荷がかかるため、１テーマごとに置換作業するのをオススメする

【注意】テーマディレクトリ中に開発環境を置いていて nodeモジュールが大量に入っている状況だと置換に高負荷がかかる。エディタによってはフリーズする可能性がある。レインボーマークがくるくる回るのをずっと見るのが好きでなければ、置換前に一旦 node_modules ディレクトリごと削除し、後で再インストールするのが良い(回線スピードの高い環境で行うこと)


## VCCW の場合

1. vccw/wordpress ディレクトリを一旦別の場所に退避
2. vccwディレクトリを対象に、テーマ名の置換を行う
3. 退避させたwordpress ディレクトリを元の場所に戻す


## ターミナル

gulp や Webpack 等の開発環境を使っていて、ターミナルのウインドウグループを設定している場合、設定し直す


## エイリアス

テーマディレクトリやSublime Text のプロジェクトファイルのエイリアス(ショートカット)を置き直す
bitFlyerのAPIを利用して建玉の情報を得るPythonコード（途中経過）

#Pythonで書いてみたはずなのだが・・・

こんにちは。プログラミング初心者です。

PythonでbitFlyerから建玉情報を得る関数を書いたつもりなのですが、なぜか「404
{u'Message': u"No HTTP resource was found that matches the request URI 'https://api.bitflyer.jp/v1/me/getpositions'."}」というエラーメッセージが出てしまう。
どこか変？

```python:position.py
def check_position():
    api_key = API_KEY
    api_secret = API_SECRET
    
    base_url = "https://api.bitflyer.jp"
    path_url = "/v1/me/getpositions"
    method = "GET"
    
    timestamp = str(datetime.datetime.today())
    
    query = { "product_code": "FX_BTC_JPY" }

    body = json.dumps(query)
    
    message = timestamp + method + path_url + body
    signature = hmac.new(bytearray(api_secret.encode('utf-8')), message.encode('utf-8') , digestmod = hashlib.sha256 ).hexdigest()
    
    headers = {
    	'ACCESS-KEY' : api_key,
    	'ACCESS-TIMESTAMP' : timestamp,
    	'ACCESS-SIGN' : signature,
    	'Content-Type' : 'application/json'
    }
    
    response = requests.get( base_url + path_url , headers = headers)
    print( response.status_code )
    print( response.json() )
```

API_KEYとAPI_SECRETはちゃんと入力してるので問題はないはず。
どこがおかしいんだろう。そもそもエラーメッセージがよくわからず。bitFlyer側で指定されたパスなんですが・・・

引き続き原因を探っていく。

5/21追記：
bodyを全部消して`path_url`に`"?product_code=FX_BTC_JPY"`を足したらとりあえず動きました。何が悪かったんだろう。
GoogleAnalytics (gtag.js)でPDFなどのファイルを仮想ページビューとして扱う方法

トラッキング用のグローバルサイトタグ（gtag.js）サイトに設置しただけではPDFなどのファイルのダウンロードした数は取得できないのですが、aタグに小細工をしかけることでできるようになったので備忘録。


#結論を先
```html
<a href="foo.pdf">foo.pdf</a>
```

こう変えるだけ

```html
<a href="foo.pdf" onclick="gtag('config', 'TRACKING_ID', {'page_path':'/FOO.PDF'})">foo.pdf</a>
```

#付帯情報は後
TRACKING_ID：自分のトラッキングID入れてください。
/FOO.PDFの部分は/で始まらなければならないそうです。

page_pathではなく、page_titleも入れることができますし、両方入れることもできます。
page_titleを指定しない場合は、ダウンロードしたページのタイトルが入りました。

##参考URL
https://developers.google.com/analytics/devguides/collection/gtagjs/pages?hl=ja
C言語でPythonのモジュール作ってみる

#C言語でPythonのモジュールを作ってみる

##環境
Python 3.4.6
gcc version 4.8.5
openSUSE Leap 42.3

##概要
Python勉強しているときに拡張モジュールの作り方が出てきて自分でも作ってみようと思った次第です。
個人的に色々つまったので、ここにノート代わりに書いておきます。

##ゴールまでの流れ
C言語でPythonのモジュールを作成
↓
Pythonを使ってCをビルドする
↓
PythonでimportしてCモジュールを使ってみる

### C言語でモジュール作成
まず、C言語でPythonのモジュールを作成していきます。
PyObject型を多用します。とりあえず、Hello_worldとpushとpop作りました。


```c:practice.c
#include <Python.h>

//Cの方で作成してPythonで利用する関数はPyObjectを使う

static PyObject* 
hello_world (PyObject *self, PyObject *args) {
  printf("Hello_world\n");
  // C側で作成する関数のreturnはPy~~...となる
  Py_RETURN_NONE;
}

static PyObject*
push(PyObject *self, PyObject *args){
  PyObject *p_list, *inthert_val, *receive_list;
  // 送られてきた値をパース
  if(!PyArg_ParseTuple(args, "O!i", &PyList_Type, &p_list, &inthert_val))
    return NULL;
  // 配列を抽出
  receive_list = PySequence_List(p_list);
  // 配列に値を追加
  printf("%dをpushします\n", inthert_val);
  PyList_Append(receive_list, Py_BuildValue("i", inthert_val));
  
  // 配列を返却
  return receive_list;
}

static PyObject*
pop (PyObject *self, PyObject *args){
  PyObject *p_list, *p_value;
  int size;
  long val;
  // 送られてきた値をパース
  if(!PyArg_ParseTuple(args, "O!", &PyList_Type, &p_list))
    return NULL;
  // リストのサイズ取得
  size = PyList_Size(p_list);
  //値を抽出 
  p_value = PyList_GetItem(p_list, size - 1);
  val = PyLong_AsLong(p_value);
  printf("%dをpopします\n", val);

  // 値を返却
  return p_value;
}

// メソッドの定義
static PyMethodDef PracticeMethods[] = {
  {"hello_world", (PyCFunction)hello_world, METH_NOARGS, "practice1: hello_world"},
  {"push", (PyCFunction)push, METH_VARARGS, "practice2: push"},
  {"pop", (PyCFunction)pop, METH_VARARGS, "practice3: pop"},
  // 終了を示す
  {NULL, NULL, 0, NULL}
};

//モジュールの定義
static struct PyModuleDef practicetmodule = {
  PyModuleDef_HEAD_INIT,
  "practice",
  NULL,
  -1,
  PracticeMethods
};

// メソッドの初期化
PyMODINIT_FUNC PyInit_practice (void) {
  return PyModule_Create(&practicetmodule);
}
```
ハマったところを箇条書きにして置いときます。
どれも調べろよっていう内容ばっかりなんですけど時間かかっちゃいました。

* 送られてきた値をパースしなければ、C側で使えないと知って延々とエラー
* Py_BuildValueしないと値をappendできない事を知らずに延々とコアダンプエラー
* Hello_world関数のような引数をとらないものはMETH_NOARGSを書かなければならないと知らずに延々とエラー
* PySequence_Listで作成したlistからの値の取り出し方が不明で悶絶。(p_list[0]では出来なかった)

個人的には、ここが一番の鬼門でした。
なので、ここさえ乗り越えられたら後は楽です。

### Pythonを使ってCをビルドする
そのままです。Pythonを使ってCをビルドします。
具体的には下記のソースを使います。

```python:setup.py
from distutils.core import setup, Extension
setup(name='practice',
        version='1.0',
        ext_modules=[Extension('practice', ['practice.c'])]
)
```
作成したら、以下のコマンドを実行してビルドします。
モジュールをインストールせずに、テストするときに使うコマンドです。

```terminal:コマンド
python setup.py build_ext -i
```
確認してみましょう。

```terminal:コマンド
ls
```

```terminal:表示
build  practice.c  practice.cpython-34m.so  setup.py
```

buildというディレクトリとpractice.cpython-34m.soというファイルが出来ました。
これでビルドは完了です。

###PythonでimportしてCモジュールを使ってみる
実際使えるか試します。
以下のコードを書きました。

```python:try_module.py
import practice as c_practice
# まずは、動作検証
c_practice.hello_world()

# push
test_list = c_practice.push([50, 51, 52], 53)
print(test_list)

# pop
result = c_practice.pop(test_list)
print(result)
```

実行してみます。

```terminal:出力
Hello_world
53をpushします
[50, 51, 52, 53]
53をpopします
53
```

とりあえずは、動きました。結構長い時間かかったので良かったです。
Alexa Skill 開発でのテストが動かない時

Alexa Skill の開発時に開発者コンソールでテストをしようとして、テストが動かない。
ハマりました。

![スクリーンショット 2018-05-20 16.34.31.png](https://qiita-image-store.s3.amazonaws.com/0/110541/bb5341bc-11e9-f180-85a4-477882f8266f.png)

この画面から一向に進まない。
そんな時は、一度ウイルスソフトAVGを開いて、WebShieldを無効化してみる。

<img width="1142" alt="スクリーンショット 2018-05-20 16.37.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/110541/3b3cedcb-4145-58ab-6c24-b9ba9432c4c6.png">

無事に動きました。
私はAVGを使っていますが、Avastでも同じな現象が起きていました。
ウイルスソフトがブロッキングしているようです。

![スクリーンショット 2018-05-20 16.45.52.png](https://qiita-image-store.s3.amazonaws.com/0/110541/f599cbcb-a4a5-5819-9b05-0f3189f2b347.png)
アプリケーションのversion/ビルド日時をAPIで確認する

マイクロサービスで多くのアプリケーションを立ち上げ、CIで自動デプロイ！というイケている現場が増えてきた昨今。とても便利で嬉しく思う反面、管理するアプリケーションが増えその分不安を覚えることも増えてきました。
私が携わっている現場では「自動でデプロイしたアプリケーションが果たして想定通りにデプロイされているのか！？」であったり、「今どのバージョンがデプロイされていたっけ？」という"動いているアプリケーション"に対する不安があがることがありました。
そこで今回はSpring Bootで作成されたアプリケーションにおいて、プロダクションコードに**手を加えることなく**バージョンを確認する機能を追加する方法を紹介します。

<img src="https://sdtimes.com/wp-content/uploads/2018/03/spring-boot.png" width="350"/>

## 対象読者
- 以下を利用してwebアプリケーション開発している
    - Spring Boot
    - Maven
- リリース後のアプリケーションの情報を外部から確認したい

## 環境
- Java 8+
- Spring Boot 2+
- Maven 3+

## 使用する機能
以下の機能を組み合わせて実現します。

- Application Info Actuator
    - :notepad_spiral: [info actuator | spring.io](https://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-endpoints.html#production-ready-application-info)
- Springプロパティの拡張機能
    - :notepad_spiral: [automatic-expansion-maven | spring.io](https://docs.spring.io/spring-boot/docs/2.0.2.RELEASE/reference/htmlsingle/#howto-automatic-expansion-maven)
    - `org.springframework.boot:spring-boot-starter-parent`を使用していることで利用可能

## 実装
### 必要な設定
アプリケーションの設定ファイルに以下を追加します。

```yml:application.yml
management:
  endpoints:
    web:
      exposure:
        include: info # 1.

info:
  application:        # 2.
    name:             @project.build.finalName@
    version:          @project.version@
    build-timestamp:  @maven.build.timestamp@
```

1. 公開するManagement Endpoint設定
    - 例では `info` のみ指定していますが、複数Endpoint設定可能 (例: `info, health`)
2. アクセスされた際に返却する情報
    - Key名は自由に命名が可能

### 確認してみる
今回はサンプルで作成した [spring-boot-automatic-expansion-maven](https://github.com/hondaYoshitaka/spring-boot-automatic-expansion-maven) にて確認してみます。
アプリケーションを起動して、Spring Boot Actuatorのinfoパス `/actuator/info` にアクセスします。

```bash
% curl http://localhost:8080/actuator/info
```
```json
{
    "application": {
        "name":"spring-boot-automatic-expansion-maven-0.0.1-SNAPSHOT",
        "version":"0.0.1-SNAPSHOT",
        "build-timestamp":"2018-05-20T13:41:45Z"
    }
}
```
期待したアプリケーションの情報を取得できました。

## まとめ

- プロダクションコードに**手を加えることなく**実現が可能
- 以下のタイミングで確認ができる
    - リリースしたアプリケーションのversionが正しいか
    - テストするアプリケーションのversionが正しいか

とても容易に実現ができるのでぜひ追加して、チームの不安を取り除いていきましょう！
TrelloAPIのdateLastActivityは使わない方が良さそう

# 結論

最初に結論を言いますと、

**dateLastActivityの日付は信用するな**

ということです。
どういうことか気になる方は以下を読み進めていただければと思います。

# Trelloとは

みなさん、ほとんどの方がご存知だと思いますが、念のため説明しておきます。
TrelloとはWeb上でタスク管理ができるツールです。
特徴として、個人的に感じるのは「操作性が快適」、「UIが綺麗」、「リロードしなくてもリアルタイム反映」などとにかく使いやすいです。
スクラム開発をする上で、「TODO, DOING, DONE」で分けて毎日の進捗をわかりやすくするカンバンという手法がありますが、それをやるにもとても使いやすく現場でも重宝しています。

https://trello.com/

# TrelloAPIについて

そんなTrelloですが、WebAPIが用意されており、APIを使うことで、カードを自動登録やデータを取得するといったことが可能になります。リファレンスやカードを取得する方法などは本記事では割愛します。きになる方は以下を参考にしていただければと思います。

APIリファレンス
https://developers.trello.com/reference/

Trello API を叩いてカードを作成する方法（curl利用）
https://qiita.com/isseium/items/8eebac5b79ff6ed1a180

# やろうとしたこと

では私が何をやろうとしたかというと

**TrelloAPIのみを使って、バーンダウンチャートを作る(DBを使わない)**

ことです。
DBを使わない理由としては、あまり大規模にしないで、ミニマムで手軽に作りたかったからです。

バーンダウンチャートについては、詳しくは書きませんが、ここら辺を参考にしていただければと思います。
https://backlog.com/ja/help/usersguide/burn-down-chart/userguide289/

簡単に説明すると、
**1スプリントのタスク消化状況を一目で見ることができるグラフ**
になります。

これを作る上で必要になることは、主に以下の3つです。

1. 1スプリント内の稼働日のリスト
1. 見積もり時間の合計
1. 各稼働日に消化したタスク時間

この中で1と2については、問題なくクリアできました。
しかし、3を取得しようとすると、doneリストの中にあるタスクがいつdoneになったかというタイムスタンプが必要になります。そこで使おうと思ったのが、このdateLastActivityなわけです。

# dateLastActivity

TrelloAPIリファレンスを見るとcardオブジェクトのプロパティの一つとして定義されています。
https://developers.trello.com/reference#card-object

ここでのdateLastActivityの説明を見てみると、、

> The datetime of the last activity on the card.

アクティビティとは、「カードを移動した」とか「カード内のチェックリスト」を更新したとかいうカードに対するアクションのことです。（だと思っていました。）
つまりdoneに追加されてからカードに対して何もしなければdoneに追加された日付が取れる。（updateのタイムスタンプが取れる！！）と思ってしまいました。

# 何がまずいか

しかし、いざAPIをコールしてdateLastActivityの値を見てみると、、(出力結果一部抜粋)

<img width="314" alt="スクリーンショット 2018-05-20 16.14.08.png" src="https://qiita-image-store.s3.amazonaws.com/0/147934/5d3f20d9-7528-d9c6-4d05-a670856e4388.png">

あれ、なんかおかしい、、、
コードレビューとか15日よりも前に終わってたきが、、
てかこれらのタスク終わったの全部5月15日12時52分っておかしいやろ！！w

もう一度リファレンスを確認すると下にちゃんとこう書いてありました。。。

> Note: There are activities that update dateLastActivity that do not create a corresponding action. For instance, updating the name field of a checklist item on a card does not create an action but does update the card and board's dateLastActivity value.

要するに、「アクションに対応しないactivity以外にもdateLastActivityは更新されることがあるよ」ということです。


ああ、なるほど。。。やはりリファレンスはちゃんと読まないとダメですね

# まとめ

まとめると、**dateLastActivityはカードを移動したタイムスタンプに使うことはできないですよ(使わない方が良さそう)**ということです。
そもそもcardオブジェクトにupdateのタイムスタンプつけてくれっていう話ですね
Mac GitHub SSH接続設定

## 前回

- [Mac Git 初期設定](https://qiita.com/ucan-lab/items/aadbedcacbc2ac86a2b3)

Gitの初期設定が行われている前提の記事です。

## Gitシリーズ記事まとめ

https://qiita.com/ucan-lab/items/33c63a402f533aa92f3e

## 背景

GitHubのリモートリポジトリにpushする際、HTTPS通信だとGitHubアカウントのパスワードを求められることがあり、毎回入力するのは面倒です。

pushの手間を減らすため、手間をかけてSSH設定しましょう！

## 目的

GitHubアカウントの認証を省略するためにSSH鍵を設定します。
複数PCを使用している場合は同じ鍵を使いまわすのではなく、各PCで鍵を登録した方がセキュリティ的に良いでしょう。

## 手順

1. GitHub用の秘密鍵、公開鍵を作成
2. GitHubに公開鍵を登録

### 1. GitHub用の秘密鍵、公開鍵を作成

GitHub用の鍵を作成する。

```
$ ssh-keygen -t ed25519 -N "" -f ~/.ssh/github
```

- `-t` : 鍵の種類を選択。安全面と性能面で最強な[Ed25519](https://ja.wikipedia.org/wiki/%E3%82%A8%E3%83%89%E3%83%AF%E3%83%BC%E3%82%BA%E6%9B%B2%E7%B7%9A%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E7%BD%B2%E5%90%8D%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0#Ed25519)アルゴリズム一択です。
- `-f` : ファイル名を指定。デフォルトは `~/.ssh/id_ed25519`
- `-N` : パスフレーズの指定。 `""` でパスフレーズなし
  - セキュリティを上げるなら設定する。今回は利便性取って設定しません。

#### 公開鍵の例: ~/.ssh/github.pub

```
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIHwbgzaHPnvXIeie2YhZubxGaxUSqMNwYKgk0YQLEIAW
```

#### 秘密鍵の例: ~/.ssh/github

```
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW
QyNTUxOQAAACB8G4M8xz571yHontmIWbm8RmsVEqjDb2CoJNGECxCAFgAAAJhtRnIqbUZy
KgAAAAtzc1gtZWQyNTUxOQAAACB8G4M8xz571yHontmIWbm8RmsVEqjDb2CoJNGECxCAFg
AAAECtf4Yrv8eb1n4AD77lT/Qh4JCfJEOEtncubpFiO2b2f5wbgzzHPnvXIeie2YaZubxG
axUSqMNvYKgk0YQLEIAWAAAAEnNhbXBsZUBleGFtcGxlLmNvbQECAw==
-----END OPENSSH PRIVATE KEY-----
```

### 2. GitHubに公開鍵を登録

```
* クリップボードに公開鍵をコピー
$ pbcopy < ~/.ssh/github.pub
```

- pbcopy コマンドを使うとファイルの中身をクリップボードにコピーしてくれます。
  - [Macな人は pbcopy が便利](https://qiita.com/mktakuya/items/c57a12b5b072a658acd0)

鍵の登録

- GitHubの公開鍵の設定画面を開く
  - https://github.com/settings/keys
- `New SSH key`
- Title を適当に入力する(PC名を入れておくと鍵管理しやすい)
- Key にクリップボードにコピーした公開鍵を貼り付ける
- `Add SSH Key` で鍵を登録する

### 3. ~/.ssh/config へ追記

```
$ vi ~/.ssh/config
Host github.com
  IdentityFile ~/.ssh/github
  User git
```

## 確認

`successfully` のメッセージが出ていればok。

```
$ ssh -T github.com
Warning: Permanently added 'github.com,52.69.186.44' (RSA) to the list of known hosts.
Hi xxx! You've successfully authenticated, but GitHub does not provide shell access.
```
秘書BOTのキャラを変えてみた

# 完成物
[初回の中間的要件](https://qiita.com/LunaChevalier/items/06706546762dfde04b44#%E4%B8%AD%E9%96%93%E7%9A%84%E8%A6%81%E4%BB%B6)にある

> 「ヨハネ，召喚」って言ったら，秘書がヨハネ様に切り替わる

という機能がついに実現しました・・・!
前回の投稿からだいぶ時間がかかってしまったのは

* ところどころバグってたので，その不具合修正してた(今回は割愛)
* 実現する方法に結構悩んでた(なんやかんやでデータベースを新規追加)
* プログラムにべた書きしてたセリフをデータベースに移行した

というのが主な理由です．
今実装されているセリフがランダムに何か返答してくれるランダム返答が↓になります．
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">最初は曜ちゃんで、｢ヨハネ、召喚｣と言うとヨハネ様に切り替わります<br>｢曜ちゃん戻って｣で曜ちゃんに切り替わります<br>画像が変わらないのはLINEの仕様なので多分どうしようも無いです… <a href="https://t.co/U1QcqOtgvB">pic.twitter.com/U1QcqOtgvB</a></p>&mdash; ルナ・チェバリー (@Luna_Chevalier) <a href="https://twitter.com/Luna_Chevalier/status/992470448620425221?ref_src=twsrc%5Etfw">2018年5月4日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

実際にスケジュールを取得するセリフも変えてみました．
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ヨハネ様が予定を教えてくれる様にしました <a href="https://t.co/fGha75AXqF">pic.twitter.com/fGha75AXqF</a></p>&mdash; ルナ・チェバリー (@Luna_Chevalier) <a href="https://twitter.com/Luna_Chevalier/status/995802670467174400?ref_src=twsrc%5Etfw">2018年5月13日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# 開発環境
* [Ruby](https://www.ruby-lang.org/ja/)(2.4.1)
* [google-api-client](https://github.com/google/google-api-ruby-client)(0.13.6)
* [line-bot-api](https://developers.line.me/ja/)(1.2.0)
* [Sinatra](http://sinatrarb.com/intro-ja.html)(2.0.0)
* [Apache](https://httpd.apache.org/)(2.4.6)
* passenger(5.1.8)
* [MariaDB](https://mariadb.org/)(5.5.56)←new!

# 主なお話
データベースの環境構築と簡単なセリフ変化のやり方です

# 現在の実装完了機能
* 文字を送信したら，ランダムで何か返事してくれる
* 「スケジュール」と送信したら，今日から1週間のスケジュールを教えてくれる
  * ベースはGoogleカレンダー
  * 当日にイベントがあったら朝に通知してくれる
* 「ヨハネ，召喚」って言ったら，秘書がヨハネ様に切り替わる(キャラが変わる)←new!

# 今回の作業
## データベースの環境構築
今回までデータベースを導入してなかったので，まずはここから．
今回から新たに[MariaDB](https://mariadb.org/)(5.5.56)を使うことにします．
CentOS7系の標準DBがMariaDBになっているので採用しています．
とは言っても，mysqlをフォークしたDBになるので，基本的な使い方はmysqlと同じです．
以下のサイトを参考にして，リモートからMariaDBにログインできるようにしました．

* [MySQL 5.7 を CentOS 7 に yum インストールする手順](https://weblabo.oscasierra.net/installing-mysql57-centos7-yum/)
* [MySQL 5.7 をインストールしたら最初に行うセットアップ](https://weblabo.oscasierra.net/mysql-57-init-setup/)
* [ユーザーの作成](https://www.dbonline.jp/mysql/user/index1.html)
* [MySQL 外部ホストからアクセスする](http://ext.omo3.com/linux/mysql_host.html)

## 構成の変更
DBを使ってセリフを管理するようになったので，全体的な構成も変更です．
今回の追加機能分だけ抽出すると下のような図になります(実際はGASが入ってきますが，今回は触ってないので割愛)．
![image.png](https://qiita-image-store.s3.amazonaws.com/0/56006/11645448-98b1-0484-ba77-26558a196ce3.png)
緑色が今回入って来たものになります．
以前まではLINEBOTのソースにセリフを直書きしましたが，今回からLINEBOTからDBにアクセスして，そこにあるセリフを取得してお話するようにしました．

ユーザーごとにキャラが設定されていて，それを使ってセリフを拾ってきます．
図のような特定の文字列を送信すると，ユーザーごとに設定されたキャラが更新され，取得するセリフが変化するようにしました．
Swift Playgroundで外部ライブラリを利用する方法

# Swift Playgroundで外部ライブラリを利用する方法

いつの頃からか激しい断絶があったようなのでまとめます。

## 正しい方法

[Carthage](https://github.com/Carthage/Carthage)を使う

## 誤った方法

[CocoaPods](https://cocoapods.org/)を使う

### 詳細

実はCocoapodsはPlaygroundをサポートしてきていなかったみたいです。これまでも動かす方法は別にあったのですが、何らかの原因でその方法を用いることもできなくなった、というのが原因のようです。次の記事に従ってみたのですが、手元の環境では動かすことができませんでした。

* [Swift PlaygroundsでXcode projectのコードを動かしてみよう - Qiita](https://qiita.com/bannzai/items/ee075bd5d651a5a24d68)
* [Swift PlaygroundsでXcode projectのコードを動かしてみよう ~~ CocoaPods ~~ - Qiita](https://qiita.com/bannzai/items/dafad16067e9c6e58ff7)

githubのIssueは例えば次のものがあります。

* [Xcode Playground support "Couldn't lookup symbols" · Issue #7371 · CocoaPods/CocoaPods](https://github.com/CocoaPods/CocoaPods/issues/7371)

それに対しての解決策の議論もなされています。

* [Playgrounds/IBDesignables can't use pod dependencies · Issue #5334 · CocoaPods/CocoaPods](https://github.com/CocoaPods/CocoaPods/issues/5334)

ではどうしようもないかというとそういうこともなく、Carthageを使えば(多少手順は複雑ではありますが)Playgroundから外部ライブラリを利用可能でした。手順は次の記事に従いました。

* [Playground で Carthage ライブラリを import する - Qiita](https://qiita.com/star__hoshi/items/b4041bc7631ceddadc52)

## 残る課題

iOSのPlaygroundはどうしたらいいのかはもう正直わからないです…。
C++ の小さな技術を紹介するシリーズ【小技C++ 全９回】＃５＜インスタンスハンドル＞

#アクセスの抽象化
銀行口座を例に考えてみよう。それぞれの利用者が口座を開設していて、その口座番号に紐づく『金庫』にお金を預けたり、引き出しているはずだ。そして、一般的には（銀行の関係者ではない限り）『金庫』の内部詳細は隠されているが、それを気にすることなくサービスを利用することができる。

>『金庫』へのアクセスを抽象化している

といえる。

抽象化することで、利用者にとっては口座番号というインターフェイスさえ知っていればサービスを使うことができる。また、銀行は金庫の内部詳細を説明しなくとも（場合によっては突然のシステム刷新をしても）サービスを提供し続けることができる。

では、ここまでの話をモデル化してみよう。

#インスタンスハンドル
まず利用者は、口座を開設すること、すなわち口座番号を発行することから始める。
この口座番号にあたるユニークな番号のことを **ハンドル** と呼ぼう。そして、サービスの窓口となる口座は、口座番号ごとに割り振られる**インスタンス** である。つまり、いま１つのインスタンスにつき、１つのハンドルが紐づけられて管理されたことになる。

このように、インスタンスに対して割り当てられるユニークなハンドルをここでは、**インスタンスハンドル** と呼ぶことにする。

#疑似コード
それでは、簡易版　銀行システムのAPI を考えてみよう。

##ハンドルを生成する
```cpp
// 例：口座を開設して、口座番号を発行する

using handle = uint64_t;
const handle kouzabangou = ginko::create_kouza();
```

ハンドルの型は必要な数を表現できるのであれば何でもよい。（上の例では、**uint64_t** を使った。）ハンドルの生成と同時に、システム内部ではハンドルに紐づけるためのインスタンスを新たに生成する。
###内部システム要件
- 新規発行のたびにユニークなハンドルを生成する
- 発行したハンドルから対応するインスタンスを検索するためのテーブルを持つ

*※内部システムの実装コードは今回の本質ではないため、取り扱いません。*

##ハンドルでアクセスする

```cpp
// 例：口座の預金額を取得する
using kingaku = uint64_t;
const kingaku yokingaku = ginko::get_yokingaku( kouzabangou );

// 例：口座に１万円を入金する
ginko::nyukin( kouzabangou, 10000 );
```
サービスを利用するときは、必要な引数に加えて、インスタンスを特定するためのハンドルを指定する。（他人の口座に入金してしまわないように…。）

##ハンドルを破棄する
```cpp
// 例：口座を解約する
ginko::kaiyaku( kouzabangou );
```
ハンドルの破棄と同時に、システム内部のテーブルによって紐づけられていたインスタンスを削除する。
##ハンドルの有効性を確認する
不正な値を持ったハンドルや、１度破棄してしまったハンドルは、有効なインスタンスを導けない可能性があり深刻な問題を引き起こす。このように不正なハンドルを使った場合に、それぞれのサービスは処理を中断して、適切なエラーを返す必要がある。もしくは、利用者が事前にハンドルの有効性をチェックするためのサービスを用意しておくことでも回避できる。

```cpp
// 例：口座番号が正当なものか確認する
const bool is_available = ginko::is_available_kouzabangou( kouzabangou );
```

#必要性
C++ に限らず、オブジェクト指向言語によって設計するサービスはクラスの集合で構成される。インスタンスが互いにメッセージを送りあうこと、つまりメンバ関数（あるいはメソッド）をコールしあうことで強く依存して動作している。一方で、リリースされてなお、日々のメンテンナンスやバージョンアップを繰り返しながら、エンドユーザからみえる姿はそのままに、その内部設計を大胆に変更するサービスは多く存在する。これらのサービスは内部実装とインターフェイス、いわゆるAPI との設計に強い依存関係があってはならない。このようなときに、今回ご紹介したインスタンスハンドルの考え方はとても効果的に働く。わかりやすく、よく知られたテクニックなので、使える場面であれば極力使っていきたいものである。
FizzBuzzを表示するhtmlファイルのコードゴルフ

普通のコードゴルフでは出尽くしてる感あるので、htmlファイルという枠で考えてみた。現実逃避で。

```html:fizzbuzz.html
<body id=b onload="for(i=0;++i<101;)b.innerHTML+='<p>'+((i%3?'':'fizz')+(i%5?'':'buzz')||i)">
```

【追記】普通にdocument.writeの方が文字数少なかった。。。

```html:fizzbuzz.html
<script>for(i=0;++i<101;)document.write(((i%3?'':'fizz')+(i%5?'':'buzz')||i)+'<br>')</script>
```
Linuxコマンドのお勉強 再帰的にパーミッションを変更

# chmodで再帰的にパーミッションを変更

```
chmod -R 777 .
```
このコマンドだと全てのファイル・ディレクトリが変更されてしまう。

# findを使用して再帰的にパーミッションを変更

## ディレクトリのみ

```
find . -type d -exec chmod 777 \{\} \;
```
## ファイルのみ

```
find . -type f -exec chmod 777 \{\} \;
```
## 拡張子指定

```
find . -type f -name '*.sh' -exec chmod 777 \{\} \;
```
Colaboratory上でSeleniumが使えないか試した(そしてダメだった)

# やりたかったこと

[前回](https://qiita.com/FrozenVoice/items/ee7713ef86c57e65b709)の続きとして、Beautiful SoupでHackMDへログイン状態でアクセスするためにSeleniumが使えないか試してみた。

# やったこと

## Firefoxのheadlessモードを試す

### 必要な物をインストール

```
!apt-get update
!apt-get install firefox
!wget https://github.com/mozilla/geckodriver/releases/download/v0.20.1/geckodriver-v0.20.1-linux64.tar.gz
!tar -zxvf geckodriver-v0.20.1-linux64.tar.gz
!cp ./geckodriver /usr/local/bin
!pip install selenium
```

### コード

```python
from selenium import webdriver
from selenium.webdriver.firefox.firefox_binary import FirefoxBinary
from selenium.webdriver import FirefoxOptions

opts = FirefoxOptions()
opts.add_argument("--headless")
browser = webdriver.Firefox(firefox_options=opts)

browser.get('http://www.google.com')
print(driver.page_source)
browser.quit()
```

### 結果

```
WebDriverException: Message: Process unexpectedly closed with status signal
```

```
!cat geckodriver.log

1526799277910	geckodriver	INFO	geckodriver 0.20.1
1526799277915	geckodriver	INFO	Listening on 127.0.0.1:49500
1526799278918	mozrunner::runner	INFO	Running command: "/usr/bin/firefox" "-marionette" "--headless" "-profile" "/tmp/rust_mozprofile.aNlqPETDAbf4"
*** You are running in headless mode.
ExceptionHandler::GenerateDump cloned child 4713
ExceptionHandler::SendContinueSignalToChild sent continue signal to child
ExceptionHandler::WaitForContinueSignal waiting for continue signal...
```

## Chromeのheadlessモードを試す

### 必要な物をインストール

```
!wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
!dpkg -i google-chrome-stable_current_amd64.deb

!wget https://chromedriver.storage.googleapis.com/2.38/chromedriver_linux64.zip
!unzip chromedriver_linux64.zip
!cp chromedriver /usr/local/bin/
```

### コード

```python
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = Options()
options.add_argument('--headless')
executable_path="/usr/local/bin/chromedriver"
service_args=["--verbose", "--log-path=/content/chromedriver.log"]

driver = webdriver.Chrome(chrome_options=options, executable_path=executable_path, service_args=service_args)

# Googleのトップ画面を開く。
driver.get('https://www.google.co.jp/')

print(driver.page_source)
```

### 結果

```
WebDriverException: Message: Service /usr/local/bin/chromedriver unexpectedly exited. Status code was: -6
```

ログ出力設定をしているつもり…なのだがファイルは生成されてなかった。
なぜWindow_Selectable.processHandling()のisOpenAndActive()は内側にあるのか

まず、以下の処理を見て欲しい。
これはWindow_Selectableという、様々なメニュー画面の根底となるクラスにある処理である。

```js:rpg_windows.js
Window_Selectable.prototype.update = function() {
    Window_Base.prototype.update.call(this);
    this.updateArrows();
    this.processCursorMove();
    this.processHandling();
    this.processWheel();
    this.processTouch();
    this._stayCount++;
};
Window_Selectable.prototype.processHandling = function() {
    if (this.isOpenAndActive()) {
        if (this.isOkEnabled() && this.isOkTriggered()) {
            this.processOk();
        } else if ( this.isCancelEnabled() && this.isCancelTriggered()) {
            this.processCancel();
        } else if (this.isHandled('pagedown') && Input.isTriggered('pagedown')) {
            this.processPagedown();
        } else if (this.isHandled('pageup') && Input.isTriggered('pageup')) {
            this.processPageup();
        }
    }
};
```

これを見て気になったことがある。
なぜ*this.isOpenAndActive()*が*processHandling()*の内側にあるのかと。
それならば、*update()*の内部でifによる分岐をした方が無駄なチェックが減ってよいのではないか。
コアスクリプトへのコミットを目的として、この部分の処理を改造した物を書いてみることにした。

そうすると、*processXXX()*な関数が4つあることに気付くだろう。
これらも内部では*isOpenAndActive()*でチェックしている。
つまり、こんな感じに改造できるのではないか。

```js:rpg_windows.js
Window_Selectable.prototype.update = function() {
    Window_Base.prototype.update.call(this);
    this.updateArrows();
    this.processCursorMove();
    if(this.isOpenAndActive()){
       this.processHandling();
       this.processWheel();
       this.processTouch();
    }
    this._stayCount++;
};
```

ここまでは考えた。
しかし、*processHandling()*内部では状態が変化する。
たとえば決定キーが押されれば、*callOkHandler()*に飛び、一度windowはフォーカスを失うだろう。
なので、全部のプロセスを*isOpenAndActive()*で囲めばいいのか？
だが、事態はそう簡単ではない。
ここにプラグインが絡んでくるのだ。

もし、プラグインによって発生した追加の入力でwindowの*isOpenAndActive()*が崩れてしまったらどうだろうか？
そうすると、本来は入力を受け付けない状態にしないといけないのに、受け付けてしまう。
決定キーとキャンセルキーが同時に押されるような事態になったら大変なことになってしまう。
また、*processHandling()*はelseを駆使して一度入力を受け取ったら他の入力は無視している。
関数を再定義したら、いつここが崩れてもおかしくはないのだ。


##まとめ
*processHandling()*内部で*isOpenAndActive()*を呼んでいるのは無駄な処理ではなく、理由のある処理だった。
これからも*processHandling()*を再定義するときは遠慮なく*isOpenAndActive()*でチェックしてほしい。
[CentOS7] firewallについての覚書

firewallについての覚書です。
補足等ございましたら、コメントください！!

##環境
OS: CentOS Linux release 7.4

## 設定の確認

### ゾーン一覧

```
# firewall-cmd --get-zones 
block dmz drop external home internal public trusted work
```

### アクティブゾーンの確認

```
# firewall-cmd --get-active-zones
public
  interfaces: eth0
```

### デフォルトゾーンの確認

```
# firewall-cmd --get-default-zones
public
```

```
## firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: eth0
  sources:
  services: dhcpv6-client ssh http https
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
```

# serviceの追加/削除(--permanet は恒久的な設定になる)
```
# firewall-cmd --add-service=service-name (--permanent)
# firewall-cmd --remove-service=service-name (--permanent)
```

## 登録済みserviceの一覧

```
ls -la /usr/lib/firewalld/services
```

## permanent オプションについて
--add-service だけでは即時反映はされるが、再起動時は元に戻ります。
--permanent を指定した場合は恒久的な設定になります。ただし、設定の際読み込みが必要です。

```
# firewall-cmd --list-services --zone=public --permanent
# firewall-cmd --add-service=http --permanent
# firewall-cmd --reload
```

## 参考
[firewalldの設定方法（基本設定編）](http://www.server-memo.net/centos-settings/firewalld/firewalld.html)
[CentOS 7 firewalld よく使うコマンド](https://qiita.com/kenjjiijjii/items/1057af2dddc34022b09e)
tyk で API Gateway を作ってみた【パート2: フリーライセンス設定編】

tykでAPI Gatewayを作りました。
本ページではフリーライセンスの設定手順を紹介します。
##実装環境
```Terminal
$ sw_vers

ProductName:	Mac OS X
ProductVersion:	10.12.6
BuildVersion:	16G1314
```
##参考文献
特になし
##前提条件
1. パート1のtykコンポーネント起動手順を完了していること。

tykでAPI Gatewayを作ってみた【パート１：コンポーネント起動編】
https://qiita.com/yuke/items/7ae1a8f128f6c9666638

##tykフリーライセンスの内容
非営利での利用であればTyk On-Premiseを無料で利用することが可能です。
ライセンスの有効期間は12ヶ月、1 nodeのみ作成することができます。
以上の制限を除くと有料のTyk On-Premiseと同じ機能を利用することが可能です。

##tykフリーライセンスの設定手順
1. tykフリーライセンスの取得
2. tykフリーライセンスの設定

###1. tykフリーライセンスの取得

####tykのホームページにアクセスして右上の「Get Started」ボタンを押下（下図の赤枠）
https://tyk.io
![スクリーンショット 2018-05-20 14.21.59.png](https://qiita-image-store.s3.amazonaws.com/0/258400/afe338a9-4740-e77d-6284-c99756085b9b.png)

####「Get a Free License」ボタンを押下（下図の赤枠）
![スクリーンショット 2018-05-20 14.22.05.png](https://qiita-image-store.s3.amazonaws.com/0/258400/3df36ace-207f-86a8-d20a-5cee6da6c51c.png)

####「Get License」ボタンを押下（下図の赤枠）
![スクリーンショット 2018-05-20 14.22.16.png](https://qiita-image-store.s3.amazonaws.com/0/258400/6fbfbc2e-f7d9-bde1-04b6-68a5e4498632.png)

####「Place Order」ボタンを押下（下図の赤枠）
![スクリーンショット 2018-05-20 14.22.29.png](https://qiita-image-store.s3.amazonaws.com/0/258400/081fa95e-0202-9d46-11f7-3d2dde5d6e31.png)

### 2. tykフリーライセンスの設定

#### メールからライセンスキーをコピー（下図の赤枠）
<img width="1230" alt="スクリーンショット 2018-05-20 14.11.05.png" src="https://qiita-image-store.s3.amazonaws.com/0/258400/2c393c4a-edcf-4c7b-ed52-b61214a0d863.png">

#### ダッシュボードにライセンスキーをペースト（下図の赤枠）、「Active Key」ボタンを押下
http://dashboard.tyk.docker:3000/
<img width="1440" alt="スクリーンショット 2018-05-19 18.01.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/258400/85bf37c8-7adf-e45b-01be-2aad817ac870.png">

#### ダッシュボードのログイン画面に遷移することを確認

![スクリーンショット 2018-05-20 15.49.02.png](https://qiita-image-store.s3.amazonaws.com/0/258400/533f03b0-8e0d-5592-5139-143f775d8d5b.png)
Python + venv を使うときのVSCode環境

#はじめに
venvを使用して開発するときの、VSCodeの設定メモ。自分用です。。
Pythonのインストールまで完了している状態。2.x系と3.x系で情報が混在しててわけわかんなかったので、基本的なところも自分用にメモ。

##環境
Windows 10
Python 3.6.5
Visual Studio Code

#仮想環境の作成と起動
PowershellかCmdを起動し、次のコマンドを実行する。
参考：[28.3. venv — 仮想環境の作成](https://docs.python.jp/3/library/venv.html)(Python公式ドキュメント)


```powershell:
PS C:\Code> python -m venv myvenv
```

フォルダが作成され、仮想環境が作成されている。

```powershell:
PS C:\Code> Get-ChildItem .\myvenv


    ディレクトリ: C:\Code\myvenv


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2018/05/20     14:59                Include
d-----       2018/05/20     14:59                Lib
d-----       2018/05/20     15:00                Scripts
-a----       2018/05/20     14:59             75 pyvenv.cfg

PS C:\Code>
```

次のコマンドで仮想環境を起動する。

```powershell:
PS C:\Code> .\myvenv\Scripts\Activate.ps1
(myvenv) PS C:\Code>
```
プロンプトの頭に`(myvenv)`と表示されていれば、仮想環境が起動できている。試しに、pipでインストールされているパッケージを確認する。

```powershell:
(myvenv) PS C:\Code> pip list
DEPRECATION: The default format will switch to columns in the future. You can use --format=(legacy|columns) (or define a format=(legacy|columns) in your pip.conf under the [list] section) to disable this warning.
pip (9.0.3)
setuptools (39.0.1)
You are using pip version 9.0.3, however version 10.0.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.
(myvenv) PS C:\Code>
```

pipとsetuptools以外、何にも入っていないことがわかる。おまけに`python -m pip install --upgrade pip`を実行しろと言っているので、素直に実行する。

```powershell:
(myvenv) PS C:\Code> python -m pip install --upgrade pip
Collecting pip
  Using cached https://files.pythonhosted.org/packages/0f/74/ecd13431bcc456ed390b44c8a6e917c1820365cbebcb6a8974d1cd045ab4/pip-10.0.1-py2.py3-none-any.whl
Installing collected packages: pip
  Found existing installation: pip 9.0.3
    Uninstalling pip-9.0.3:
      Successfully uninstalled pip-9.0.3
Successfully installed pip-10.0.1
(myvenv) PS C:\Code>
```

ここまで完了したら、好きなパッケージをインストールして開発を進めればよい。

#VSCodeの設定
ここが本題。
VSCodeのPythonエクステンションのSettingファイルにも設定を記載する箇所があるようだけど、よくわかんねーでした。
結局、仮想環境を起動したプロンプトからVSCodeを起動するという古典的な方法に落ち着きました。これ以外に何か方法ないのかな・・・。

次のファイルを`myvenv`フォルダへ作成して実行すれば、仮想環境の環境変数が引き継がれ、VSCode上のLintやパッケージの導入状態が引き継がれる模様。

```powershell:Invoke-Code.ps1
Set-Location $PSScriptRoot
.\Scripts\Activate.ps1
& "C:\Program Files\Microsoft VS Code\Code.exe" .\
```

なお、Powershell V2以前は、`$PSScriptRoot`が使えないので、バージョンアップするか、`Split-Path $MyInvocation.MyCommand.Path -Parent`にしてください。
【C#版】Windows10のロック画面を壁紙にする

[Windows10のロック画面の画像がキレイだから壁紙のスライドショーにしたいと思った](https://qiita.com/hsn/items/e80fcf88839ab64eba81)の記事がすごくよく、自環境でも実行したかったがJavaの実行環境がなかったため諦めてC#で書き直したので共有します。

# コード

```cs:PictureMaker.cs
using System;
using System.Drawing;
using System.IO;

namespace StockWallPaper {
    public class PictureMaker {

        private static readonly string _destFolder = 
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyPictures), "LockPictures");

        private static readonly string _windowsLockPictureFolder =
            Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets");

        public static void GetLockPictures() {
            foreach (var picturePath in Directory.GetFiles(_windowsLockPictureFolder)) {
                try {
                    using (var bmp = new Bitmap(Image.FromFile(picturePath))) {
                        if (bmp.Width == 1920) {
                            //コピー先はjpg形式とする。
                            string destFileName = Path.Combine(_destFolder ,Path.GetFileName(picturePath) + ".jpg");
                            File.Copy(picturePath, destFileName, true);
                        }
                    }
                }
                catch (OutOfMemoryException) {
                    //ファイルのロードに失敗する場合は次へ行く。
                }
            }
        }

        public static void MakeLockPictureFolder() {
            if (Directory.Exists(_destFolder) == false) {
                Directory.CreateDirectory(_destFolder);
            }
        }
    }
}

```

```cs:Program.cs
namespace StockWallPaper {
    public class Program {
        public static void Main(string[] args) {
            PictureMaker.MakeLockPictureFolder();
            PictureMaker.GetLockPictures();
        }
    }
}
```

# 感想
クラス名とかコードとかゴミだけど、とりあえず動くからよしとしてくださいm(__)m