OmniAICreator/Qiita-1.07M huggingface dataset:
SentiWordNet を日本語化する

Sentiment Analysisに使えるデータセットとして[SentiWordNet](https://sentiwordnet.isti.cnr.it/)というものがあります。これは、概念 (synset) ごとにポジティブ値とネガティブ値、そして例文がついています。具体的には以下のようになっています。

```
a	00001740	0.125	0	able#1	(usually followed by `to') having the necessary means or skill or know-how or authority to do something; "able to swim"; "she was able to program her computer"; "we were at last able to buy a car"; "able to get a grant for the project"
a	00002098	0	0.75	unable#1	(usually followed by `to') not having the necessary means or skill or know-how; "unable to get to town without a car"; "unable to obtain funds"
```

しかし日本語版が提供されていないので、今回はこれを無理やり日本語化しようと思います。

やり方は単純に[日本語WordNet](http://compling.hss.ntu.edu.sg/wnja/)のDBを利用してSentiWordNetのsynsetから日本語の見出し語を取得して、例文は[Google Apps Scriptを使って翻訳](https://qiita.com/tanabee/items/c79c5c28ba0537112922)します。

コードはこちら
https://gist.github.com/ikegami-yukino/2a5ed3fd3ccde2938f020e47a8e4c9af
実行するには、SentiWordnet 3.0と日本語WordNetのDB (Japanese Wordnet and English WordNet in an sqlite3 databaseって書いてあるやつ) のダウンロードと、Google Apps Scriptの`Please_write_here`の部分を書き換えるのと、requestsのインストールが必要です。

実行すると以下のような結果が得られます。

```
00001740-a	可能	0.125	0	泳げる,彼女は自分のコンピューターをプログラムできた,ついに車を買うことができました,プロジェクトの助成金を得ることができる
00002098-a	できない	0	0.75	車なしでは町に行けない,資金を獲得できない
```

ただし例文の翻訳が下記のように微妙なことが多々あります。

```
古い世界をかき回した活発な議論によって触れられないそのささいな地方主義でシチュー
彼の頭は種を蒔くために行ってタンポポのようにあいまい
部屋は窒息していた - 暑くて空気のない
```

また、英語から日本語に訳す際にニュアンスが変わってしまう言葉があったりするので、このデータをそのままつかうのではなく、シードとして誤りを正すなり除外するなりしたほうがいいと思います。お金があれば翻訳処理の箇所を有償サービスのものに書き換えてみるのも手です。
Daru::Viewで都道府県のマップを描いてみた

都道府県別のデータを[RESAS-API](https://opendata.resas-portal.go.jp/)から取得して[Daru::View](https://github.com/SciRuby/daru-view)でグラフを描いてみました。本家のサンプルに国ごとのマップを描く方法は載っていますが、県別にマップに色つけする方法がなかったので記録を残します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/144608/cf3c2f62-50f5-7e43-544b-76650ba318c8.png)

#### 前提となる環境
* Jupyter Notebook / Lab
* IRuby

#### Daru::Viewとは？
Ruby用のデータフレーム Daru のライブラリ。バックエンドにGoogle Chartsや、Highchartsを利用する。Google Chartsの基本的な機能はほぼカバーされている。
https://github.com/SciRuby/daru-view

```ruby
require 'daru/view'
require 'resas_kit'
```

RESAS-APIから情報の取得するのは[ResasKit](https://github.com/emsk/resas_kit)というGemを利用した。（Qiitaに[作者による解説記事](https://qiita.com/emsk/items/9891ea199f2d5a803aa9)があります）

```ruby
client = ResasKit::Client.new(api_key: KEY) # キー取得には登録が必要
```

都道府県のリストを取得。あとでGoogle Chartに投げるために「県」「都」「府」を消しておきます。

```ruby

prefs = client.get('prefectures').body.result.map do |item|
    name = item.prefName
    name.chop! unless name == "北海道"
    [name, item.prefCode]
end
#[["北海道", 1],
# ["青森", 2],
# ["岩手", 3],
# ...
# ["沖縄", 47]]
```

## 都道府県別の総人口を取得する
今回は練習のため、県ごとの総人口を取得してみます。

#### データの取得
県別のデータを一括して取得する方法がわからなかったので、ここではループをまわして取得しています。

```ruby
population_data = prefs.map do |name, n|
    hoge = client.get 'population/composition/perYear', pref_code: n
    value = hoge.body.result.data[0].data[12].value # 12 は 2020年のデータ
    population_data << [name, value]
end
```

#### データフレームの作成

```ruby
df = Daru::DataFrame.rows(population_data)
df.vectors = Daru::Index.new ["都道府県","総人口"]
df.head 3 # 上から3行を表示して確認
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144608/a9d90885-f572-70f6-e33a-cc040fb9323c.png)


今回は使いませんが、nilの除去をする場合は下記のようにしたりします。

```ruby
df.replace_values nil, 0 # nilを0に変換する
```



#### 都道府県のチャートを描く

```ruby
Daru::View::Plot.new(df,
    adapter: :googlecharts,
    region: 'JP',
    resolution: 'provinces',
    type: :geo,
    height: 500, width: 800
    ).show_in_iruby
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/144608/898e7e8d-21d6-7954-0712-cb9a044b956f.png)

おまけで、円グラフや棒グラフも描いておきましょう。
#### 円グラフ

```ruby
df2 = df.sort(["総人口"], ascending: false)
# ↑ ソートをかけた
Daru::View::Plot.new(df2,
    type: :pie,
    height: 500, width: 800
    ).show_in_iruby
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/144608/cd819b69-1b2c-72f7-40ff-7eeee45f99c6.png)

### 棒グラフ

```ruby
Daru::View::Plot.new(df,
    adapter: :googlecharts,
    type: :bar,
    vAxis: {textStyle: {fontSize: 8}},
    height: 800, width: 800
    ).show_in_iruby
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/144608/2988c4c0-adec-a6a0-75b4-64aa507fce55.png)

　上記のコードを少し書き換えるだけでも、さまざまなグラフが作成できそうです。

　Pythonのすばらしい可視化ライブラリには遠く及びませんが、使用頻度の高い古典的なグラフについてはかなり便利に使えるのではないでしょうか。

　余談ですが、上記の簡単なコードを書くのには実はそれなりに時間がかかっています。初めて見たAPIで何の情報がどこに格納されているかを探すのに、かなり時間がかかるようです。

　この記事は以上です。
power-assert をインストールするときはテストコードの配置場所に注意しよう

## はじめに

power-assert[^1] は便利なライブラリですが、インストールでハマったのでその記録と対処について書きます。

[^1]: https://github.com/power-assert-js/power-assert

## エラーの表示が変わらない。。

筆者の環境だと、公式ページの説明の通りインストールしても、エラーの表示が Node.js 標準の assert から変わりませんでした。

```package.json
{
  "name": "power-assert-sample",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "test": "mocha --require intelli-espower-loader tests/*.js"
  },
  "devDependencies": {
    "intelli-espower-loader": "^1.0.1",
    "mocha": "^5.2.0",
    "power-assert": "^1.6.1"
  },
  "dependencies": {
  }
}
```

```src/hello.js
module.exports = (person) => {
  return `Hello, ${person}!`;
}
```

```tests/helloTest.js
const assert = require('power-assert');
const hello = require('../src/hello.js');

describe('hello test suit', () => {
  it('greet Taro', () => {
    assert(hello('Taro') === 'Hello, Taro!');
  });
});
```

### テスト実行

```
yarn test
```

```
  1) hello test suit
       greet Taro:
     AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:

  func.apply(thisObj, args)
```

## 原因

power-assert を使うとき、テストコードは `test` に置くことを想定していますが、私のリソースでは `tests/` においていました。

テストのディレクトリが `test` と異なる場合は package.json に明示的に指定するとのこと。
**内部で構文解析をしているので、テストコードの場所を知っている必要がある**んですね。

このことは、 `power-assert` でなく、 `intelli-espower-loader` の README[^2]に説明がありました。

> **The default folder is "test/". You must put your test script in this folder**.
> If you don't put your test code in the right folder, intelli-espower-loader will work incorrectly.
> **You can change test folder setting in your package.json**

[^2]: https://github.com/power-assert-js/intelli-espower-loader#1-put-test-script-in-test-folder

package.jsonを以下を追加したらうまく動きました。

```
...
  "directories": {
    "test": "tests"
  },
...
```

```:表示結果
  assert(hello('John Smith').match(/^Hello, Taro/))
         |                   |
         |                   null
         "Hello, John Smith!"
```
## 参考
TeX条件分岐(編集中NOT)

#if 条件分岐
`\ifthenelse`が便利

パッケージの宣言が必要になります。

```tex
\usepackage{ifthen}
```

## 使い方

```tex
\ifthenelse{#条件}{#実行その1}{#実行その2}
```
`#条件`を満たすと，`#実行その1`が実行されます。満たさない場合は，`#実行その2`が実行されます（elseですね）。何も書かなければ，何も実行されません。

`#条件`で扱える数値は，そのままでは整数値だけなので注意が必要です。実数値（小数の値）を条件に入れたい場合，`\lengthtest{ 小数値の条件 }`を使います。たとえば，


```tex
\ifthenelse{\lengthtest{ \length pt < 4 pt}}{#実行その1}{#実行その2}
```

と書いたとき，変数`\length`が4よりも小さいときという条件になります。ただしlengthからもわかるように，本来は長さを比較するもののようです。注意が必要で，必ず単位をつけます（pt，cm, mm など何でもよし）。

実際に使う場合は次のような形になることが多いです。

```tex
%単位をつけることを忘れないように
\ifthenelse{\lengthtest{ \varA pt < \varB pt}}{#実行その1}{#実行その2}
```


## AND OR

```tex
\ifthenelse{ 条件1 \AND 条件2}{#実行その1}{#実行その2}
\ifthenelse{ 条件1 \OR 条件2}{#実行その1}{#実行その2}
```

`\lengthtest`を使う場合は

```tex
\ifthenelse{ \lengthtest{ \varA pt < \varB pt} \AND \lengthtest{ \varA pt < \varC pt}}{#実行その1}{#実行その2}
```

と記述します。


## NOT
Rails で rubocop-rspec を使うときは、 rubocop-inflector も一緒に使うと便利

# TL; DR

RSpec と Rails を一緒につかって開発するときは、  [`rubocop-inflector`](https://github.com/aeroastro/rubocop-inflector) を gem install した上で、以下のような `.rubocop.yml` にすると、 Railsで利用している語形変化（ `ActiveSupport::Inflector` の設定）がそのまま rubocopにも適用されます。

`.rubocop.yml`

```yaml
require:
  - rubocop-rspec # If you are using rubocop-rspec, this should come first.
  - rubocop-inflector
  - ./config/initializers/inflections # Your custom rule file
```

`config/initializers/inflections.rb`

```ruby
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.acronym 'RuboCop'
  inflect.acronym 'PvP'
end
```

# RuboCop とは？

Rubocop は、Rubyのコードを静的解析してくれて、フォーマットを整えてくれる君です。
とても便利なツールなので、常日頃お世話になっている方が多いのではないでしょうか？

https://github.com/rubocop-hq/rubocop

> RuboCop is a Ruby static code analyzer and code formatter. Out of the box it will enforce many of the guidelines outlined in the community Ruby Style Guide.

そして、 `rubocop-rspec` とは、RSpecに対しても、フォーマットを整えてくれる君です。

https://github.com/rubocop-hq/rubocop-rspec

チーム開発でRailsを利用する場合は、フォーマットに対して不毛な時間を費やさないためにも、これらは是非導入しておきたいところです。

# `rubocop-rspec` を単体で使った場合の問題点

RuboCop は非常に良いツールです。そして `Rubocop::RSpec` もそのとおりです。
しかし、Railsを使って開発していると、かゆいところに手が届きづらいということがあります。

## 例: `RSpec/FilePath` について

このcopは、RSpecのファイルパスと、RSpec内でのテスト対象が一致しているかをチェックしてくれます。

https://www.rubydoc.info/gems/rubocop-rspec/RuboCop/Cop/RSpec/FilePath

例えば、以下のようなテストファイルに対して、ファイル名が不適切だと指摘してくれます。

```ruby
# my_class_spec.rb
describe MommyClass do # ファイル名も mommy_class_spec.rb にしろとおこられる
end
```

これは内部的には、対象を snake_case にした結果がファイル名と一致しているかを確認しています。
しかし、単純に snake_case にするのではなく、例えば、 `RuboCop` を `rubocop` に変換するように、いくつかの言葉は一つの言葉として snake_case にしなければなりません。 `rubocop-rspec` を単体で利用する場合は、このような言葉は 設定値の `CustomTransform` に追加することで対応することが出来ます。

例えば、`PvP`という言葉を使っている場合は、以下のような設定値を書くことでこれを回避できます。

```yaml
RSpec/FilePath:
  CustomTransform:
    PvP: pvp
    SyncPvP: sync_pvp
    AsyncPvP: async_pvp
    PvPOverPvP: pvp_over_pvp
    PvPController: pvp_controller
```

しかし、`CustomTransform`は完全一致であるため、利用しているパターンの数だけ書く必要があります。
そして、Railsを使っている方ならお気づきかもしれませんが、このような設定値ってどこかで見た記憶がありますよね？

# `rubocop-rspec` も一緒に利用する場合

そうです。 `config/initializers/inflections.rb` に記述している `ActiveSupport::Inflector` の設定が、今回の問題を解消するための鍵になります。そして、この設定を簡単にrubocopに反映してくれるのが、以下の `rubocop-inflector` になります。

https://github.com/aeroastro/rubocop-inflector

これを導入することで、以下のような簡潔な設定を書くだけで、特殊な言葉への対応が完了します。そして、これらは Rails での inflector と同じ設定であるため、実際のコードと、Rubocopの設定が同期的にメンテナンスされるというメリットもあります。

```yaml
require:
  - rubocop-rspec # If you are using rubocop-rspec, this should come first.
  - rubocop-inflector
  - ./config/initializers/inflections # Your custom rule file
```

```ruby
ActiveSupport::Inflector.inflections(:en) do |inflect|
  inflect.acronym 'PvP'
end
```

この `rubocop-inflector` はリリースされたばかりですが、非常に薄いgemであり、これを導入することで、Rubocopの設定ファイルのメンテナンスが非常に楽になるので、`rubocop-rspec` を Rails で利用されている方は、是非利用してみることをおすすめします。
【R】RODBC経由でSQL Serverからデータ取得。

環境　
Windows 
R 3.2.5
Microsoft R Open 3.2.5

#Windows認証を使ってRODBCでSQL Serverに接続
RからRODBCパッケージを使ってSQL Serverに接続する。

~~~r
library(RODBC)
#データベース接続
setDB<-function(){
  driver<-'{SQL Server}'
  server <- 'localhost\\SQLEXPRESS' 
  database <- 'NicoNico' 
  trusted_connection <- 'yes'
  conn<-paste('DRIVER=',driver,';SERVER=',server,';DATABASE=',database,';Trusted_Connection=',trusted_connection,';',sep="")
  cnxn <- odbcDriverConnect(conn)
  return(cnxn)  
}
~~~

#SQL構文でデータ取得
返り値はdateframe。適宜date.table等に変換すると使いやすいかと。

~~~r
conn <- setDB()
sqlText <- "select * from [dbo].[Hoge];"
videoData<-sqlQuery(conn, sqlText)
~~~

#結果
RからSQL Serverに接続、データを取得できた。
あとはR側で統計分析すればOK。

参考
http://www.okadajp.org/RWiki/?RODBC
イベントをもっと制御してみる[PocketMine-MP]

# 注意
**PMMP3.x**向けの記事です。
バージョン4以上をお使いの方はあてにしないで。あくまで参考までに。いつか更新します




#はじめに

PocketMine-MPには、プラグインで
マーカーインターフェースのListenerを持つクラスに
任意のイベントを引数としたメソッドを用意し、
イベント処理を行わせる機能があります。

その中で、今回触れるのは PHPDocを使って動作を制御する方法です。

何故使っているものを見ないのだろうと疑問に感じたので
書いていきます。
(そもそも使う機会そんなにないのかな...とか)
　


# イベントを実行させる順序
**イベント**において、
どのプラグインのイベント処理が先に行われるか考えたことはありますか？

私は、PlayerJoinEventでのネームタグ操作処理で、その考えがよぎりました。

例えば、``$player->setNameTag("[ahehe]".$player->getNameTag())``
としたとき、
同じイベントを持つ別のメソッドで、``$player->setNameTag("[ohoho]".$player->getNameTag())``
と書いてあると想定します。


**[ohoho][ahehe]MyDeacy**  みたいにしたいのに、順序のわからない状態だと
**[ahehe][ohoho]MyDeacy** となってしまうかもしれません。
ややこしい。

そこを解決してくれるのがこれ
**``@priority <優先度>``**

PHPDocの中に書き、こんな感じになります。

```php
/**
 * @priority HIGH
 */
function onJoin(PlayerJoinEvent $event){
    //処理
}
```

``@priority``の次に優先度を記入することで
イベントの実行順を操作できます。

順序は、実行が速い順から
LOWEST → LOW → NORMAL(これが通常) → HIGH → HIGHEST → MONITOR
となります。

(単語の意味的に順序逆な気もしますが、流石PMMPですね。)

　


# このプラグインがないとイベント処理しない
~~「あなたがないと これやらないわ！」
メンヘラみたいですね。~~

プラグインの__依存関係__を定義することができます。

書き方は↓↓

**``@softDepend [PluginName]``**


PluginNameは該当のプラグインの名前をいれ、
そのプラグインが有効でない状態ならば
イベントを引数に置いたそのメソッドはコールされません。

これは割と使い道あるのではないでしょうか。


使用法です。
前述の例と同様に記載します。

```php
/**
 * @softDepend EconomyAPI
 */
function onJoin(PlayerJoinEvent $event){
    //処理
}
```
　



# キャンセルされたイベントならば処理しない

このように記載します。

**``@ignoreCancelled``**

タイトルではピンと来ないかもしれません。

前述の、イベントの実行順序に絡んでおり、
前に実行されたメソッドで、
自分が引数として持っているイベントが**キャンセルされていない場合**、
これをPHPDocに持ったメソッドはコールされます。

分かりにくいと思うので例を。

先に、イベント発火時に このメソッドが実行されていたとします。

```php
function onJoin(PlayerJoinEvent $event){
    $event->setCancelled(); //イベントをキャンセル
}
```
　
その次に実行されたこのメソッドは、
イベントがキャンセルされたため ハンドラに渡されず、
**コールされることはありません。**

```php
/**
 * @ignoreCancelled
 * @priority HIGH
 */
function onJoin(PlayerJoinEvent $event){
    $event->getPlayer()->sendMessage("anpon");
}
```

　
# 実行させない

メソッドをイベントハンドラではないとみなし、
イベントが発生した際、そのイベントを引数に持っていたとしても
メソッドはコールされなくなります。

書き方↓↓ 　今までの例のように記載するだけです。

**``@notHandler``**
　
#おわりに
機能をメモがてら記事に書き起こしましたが どうでしょう。
少しでも参考になると幸いです。

ここにあらかた書いてあるんですけどね。

[pocketmine/event/Listener.php](https://github.com/pmmp/PocketMine-MP/blob/master/src/pocketmine/event/Listener.php)


~~それにしても優先順序 low → high は謎である。~~
☝とか言ってたけど、これ実行順じゃなくて優先度を意味してるからそりゃそーだよね
Yaraの勉強#1

##Yaraを使ってみた
Yaraはマルウェア等を検出するために使用できる、パターンマッチングツールです。使い始めるまでの流れを備忘録的にまとめます。


>YARA is a tool aimed at (but not limited to) helping malware researchers to identify and classify malware samples. With YARA you can create descriptions of malware families (or whatever you want to describe) based on textual or binary patterns.
>>Welcome to YARA’s documentation!
>>https://yara.readthedocs.io/en/v3.8.1/

##Yaraのインストール
Ubuntu18.04で以下のコマンドを実行します。
どのパッケージがなぜ必要かまでは、まだ理解できていません。

```commands.sh
#アップデート
sudo apt-get update
sudo apt-get upgrade
sudo apt-get -y install automake libtool make gcc yara python3-yara
#作業用ディレクトリとして/yaraを作成
mkdir yara
cd yara
```

##Yaraルールの作成
極めて簡単なルールを作成していきます。
検出対象のテストファイルとして、以下の`test.txt`を作成します。（もちろん、ノーマルファイルですw）

```test.txt
This is a test file!
```

そして、このテストファイルを検出するためのルールを`TestRule.yara`として作成します。
要件としては以下にします。

- "This is a test"にマッチすると検出する
- 検出ルール名は"ExampleTestfileRule"

```TestRule.yara
rule ExampleTestfileRule
{
    meta:                                                             
        description = "This is example file"                            
                                                 
    strings:
        $text_string = "This is a test"
        $text_binary = {54 68 69 73 20 69 73 20 61 20 74 65 73 74}

    condition:
        $text_string or $text_binary
}
```
サンプルをいくつか見ていると、metaの書き方もまちまちですが、お作法的なこともあるんですかね？
このあたりはまた改めて調べてみたいです。

##検出テスト
では、スキャンを実行してみましょう。以下のコマンドを実行します。

```commands.sh
yara TestRule.yara test.txt
```
すると、以下の実行結果が得られ、検出に成功したことがわかりました。

```
ExampleTestfileRule test.txt
```
なるほど、「ExampleTestfileRule 」で「test.txt」を検出したってことですね。

##おわりに
Yaraの最初の一歩を踏み出すことができました。これからルールの書き方等勉強していきたいと思います。

##参考文献
YARA’s documentation
https://yara.readthedocs.io/en/v3.8.1/

YARAについて
https://digitaltravesia.jp/usamimihurricane/webhelp/_RESOURCE/MenuItem/another/anotherAboutYARA.html

Yara - くじらとたぬき
http://kmdnet.hatenablog.com/entry/2016/10/24/215353

なにやら(yara) - じゃあ、おうちで学べる
http://syu-m-5151.hatenablog.com/entry/2016/09/15/045006
power-assert 使ってますか？

## power-assert とは？

和田卓人さんが開発した javascript のアサーションのライブラリ[^1]です。
普通のアサーションと比べて、**簡単な書き方でより多くの情報を提示してくれます**。
しかも、既存のテストコードに node.js 標準の assert を使っている場合は、 require の部分を差し替えるだけで移行することができます。

以下、Node.js標準のアサーションライブラリと表示を比較してみます。

## power-assert のないとき 😔

### サンプルコード

```src/hello.js
module.exports = (person) => {
  return `Hello, ${person}!`;
}
```

```test/helloTest.js
const assert = require('assert');
const hello = require('../src/hello.js');

describe('hello test suit', () => {
  it('greet Taro', () => {
    assert(hello === 'Hello, Taro!');
  });
});
```

### 実行結果

```
AssertionError [ERR_ASSERTION]: The expression evaluated to a falsy value:
```

評価が false だった、ということしかわかりません。


## power-assert があるとき 🤣

### サンプルコード

```src/hello.js
// 同じ
```

```test/helloTest.js
const assert = require('power-assert');
// あとは同じ
```

### 実行結果

```出力結果
  assert(hello === 'Hello, Taro!')
         |     |
         |     false
         #function#
```

assert が評価されたときの前後の式の評価値まで知ることができます。

## 何が嬉しいか？

**簡単な書き方で豊富な情報を得られること**。

ほかのテストライブラリで同じ情報を得ようとすると、assertEqual(), hasAnyKeys(), ...など、**検査項目をいちいち指定してやる必要がありました**。「オブジェクトを比較する場合は `assertDeepEqual()` 」といったように、検査項目に対応する書き方を覚える（もしくはマニュアルを調べる）必要がありました。

一方、 power-assert は `assert()` 1つで十分な情報を得ることができます。

例えば、検査対象の文字列が特定の正規表現にマッチするかを調べたい場合、以下のように書けます。

```js:test/helloTest.js
  it('greet Taro', () => {
    assert(hello('John Smith').match(/^Hello, John-Smith/));
  });
```

```:実行結果
  assert(hello('John Smith').match(/^Hello, John-Smith/))
         |                   |
         |                   null
         "Hello, John Smith!"
```

使っているメソッドは `assert()` だけですが、テストに失敗した原因を知るための十分な情報を得ることができます。

## なんでこんなことができるのか？

テストコードの構文解析をしているためです。
アーキテクチャの詳細な説明は参考資料にあげているスライド[^2]を見てください。

## 終わりに

Javascript の便利で強力なアサーションライブラリーである power-assert について紹介しました。


## 参考

[^1]: https://github.com/power-assert-js/power-assert
[^2]: https://www.slideshare.net/t_wada/powerassert-in-javascript
TeXのカウンターと繰り返し処理（TeX・Tikzで数値計算）

カウンターは，TeX方式と新しいLaTeX方式のものがあります。両方とも，LaTeXで使用できます。

## TeX版

カウンターの定義`\newcount`

```tex

\newcount\counterA

```

カウンター`\counterA`が定義されます。
TeX方式では，カウンターは`\`を付けたもので扱う。LaTeXと異なり，コレ自体が数値になります。カウンターの取れる値は，(負の数も含め)整数です。

### 代入
```tex
\counterA=#整数
\counterA=#カウンター名
```
1行目は，`\counterA`に整数値を代入することを意味しています。2行目は，別のカウンターの値を代入することになります。

### 演算

和

```tex
\advance\counterA by #整数
```

積

```tex
\multiply\counterA by #整数
```

割り算

```tex
\divide\counterA by #整数
```

計算結果が小数になった場合は小数点以下を切り捨てる。
TikZの中で値を参照することができる。



## LaTeX版

カウンターの定義`\newcounter`
ちょっと違うので注意。

```tex
\newcounter{counterA}
```

カウンターcounterAが定義される。LaTeX方式では，カウンターに\はつかない。LaTeXでは，カウンターのもつ数値を参照するために，特別なコマンドが必要になります。

代入

```tex
\setcounter{counterA}{#整数}
```


別のカウンターの値を代入することもできるが，TeX式と違い注意が必要。
カウンターの数値を参照しなければいけません。

```tex
\setcounter{counterA}{\value{#別のカウンター}}
```

`\valueは`，カウンターの値を参照するコマンド。
同じようなコマンドに，`\arabic`があり，

```tex
\arabic{counterA}
```

でcounterAの値を文字として表記することができる。

### 演算

和

```tex
\addtocounter{counterA}{整数}
\addtocounter{counterA}{\value{別のカウンター}}
```

積・割り算はありません。


私の経験では，TikZの中では使用できない（中で値を参照しようとすると，エラーがでる。nodeで，表記する場合は大丈夫）。

## TeX版で繰り返し処理・ループ

私が，くり返しの演算で使うのはTeX版のカウンターです。`\tikzmath`と組み合わせて使うのに非常に便利です。

```
\newcount\countA

\countA = 0 \loop\ifnum\countA < 10
{
・・・内容・・・
}
\advance\countA by1\repeat
```

これで10回の繰り返しの処理を行います。

## 参考URL
http://www.geocities.co.jp/HeartLand-Poplar/1240/latex/value.html なくなりました。
RStudioの文字コード設定

## 現象
RStudioをインストールし、先輩からもらったソースコードも見ようとしたら、文字化け。
調べてみたら文字コードの設定だった
![文字化け.PNG](https://qiita-image-store.s3.amazonaws.com/0/330493/b3f2032d-86e0-dbd8-d193-c7369df57de2.png)



## 設定の仕方
1.【Tools > Global Options】を選択
![設定1.PNG](https://qiita-image-store.s3.amazonaws.com/0/330493/a8370214-ee52-a423-d988-884cbdfbe831.png)

2.【Code > Saving】を選択
![設定2.PNG](https://qiita-image-store.s3.amazonaws.com/0/330493/fad56f3b-f4d4-1b2f-ca73-ac3003e8c8ad.png)

3.【Defalut text encoding > change > 該当の文字コード】を選択
![設定3.PNG](https://qiita-image-store.s3.amazonaws.com/0/330493/91d7a7ca-e039-242e-30fb-054df4acbc91.png)

設定をしただけだと、表示が変わらないので一度ソースをバツ印で消して、RStudioを起動しなおすと文字コードが戻った。
mermaid.jsを使ってみた

## はじめに
* mermeid.jsは簡単なフロー図などをmarkdownで書けるライブラリです
* github, VSCode対応のExtentionも出て使い勝手良さそうなので簡単に紹介してみます

## mermaid.jsの紹介
https://qiita.com/uzuki_aoba/items/a01f8b0b52ced69c8092
とてもすばらしくわかりやすい。もう追記することがない。
↓に紹介するExtensionを入れると、githubなどでも使えるようになります。

## 関連ツールの紹介
### githubでmermaid.jsを描画できるようにする
以下のExtensionを入れて開くだけ。
https://chrome.google.com/webstore/detail/mermaid-diagrams/phfcghedmopjadpojhmmaffjmfiakfil

↓確認用にgithubに簡単な図を上げてみました。
https://github.com/lc-shimazaki/qiita-sample/blob/master/mermeidjs/README.md

### VSCode
以下のExtensionを入れてMarkdownでPreviewするとmermaid.jsで描いたフローが描画できます。
https://marketplace.visualstudio.com/items?itemName=bierner.markdown-mermaid

Atomとかにもあるので、割といろんなエディタで似たようなツールがあるはず。

## 所感
* 自分１人のためのドキュメントや、簡単なプレゼンで使う分には結構いい！
* でもチームで使うほどかは微妙、自己満ツールかも
  * 複雑な図は管理しづらい
  * そもそも図が変わるようなことってあんまないだろうから無理に差分管理とかする必要もない気がする
  * でも少人数チームとかで、軽く声かけたらExtension入れてくれるような感じなら使っていいんじゃないかなぁ
WebGLによる正距方位図法の地図の経緯線描画


正距方位図法で描画した地図に対する経緯線の描画をWebGLで実装する方法。

経線・緯線に沿った点列を生成しそれを正方向の投影変換を掛けた上でラインとして結合して描画する方法ではなく、逆方向の投影変換を用いてほとんどの演算をWebGL側で実施し描画する方法について。


# 目的
- 画像を正距方位図法で投影して描画した地図上に経緯線を重ねたい。
 - 参考: [WebGLによる画像の正距方位図法への投影変換](https://qiita.com/tomosn/items/472bd6f4ff09c6926f6e)
- JavaScriptで点列を生成して曲線を描画する方法ではいくつか難点があり、それを改善したい。
 - 特にパフォーマンス面を改善したい。

# 以前の方法
当初は経緯線の描画として以下のような方法を使用していた。考え方としてはごく普通の方法。

- 緯度経度座標系上で、緯度あるいは経度が固定の値をとる点列を生成。
- 生成した点列に対して正方向の投影変換で座標変換を実施。
- 変換した点列を元にラインとして結合して描画。

この方法は考え方はシンプルだが、以下のようなデメリットがある。

- 滑らかな曲線を描画しようとすると、密な点列を生成する必要がある。
- 外周部（対蹠点）付近では、いくら点列を密に生成したところで大きな飛びが発生してしまう。
 - 上記の結果、滑らかな緯線・経線を描画しようとすると、処理が結構重くなる。
- 外周部（対蹠点）付近での飛びの対策や、曲率の変化に応じた点列の密度の調整などを考慮すると、点列の生成処理が簡単ではなくなる。

特にスマホなどの端末ではパフォーマンス上の問題が大きく、これを改善するために次のような抜本的な変更を行った。

# 改善した方法

## 概要
改善した方法では、正方向ではなく逆方向の投影変換を使用する。予め点列を生成することも行わない。基本的にほとんどの演算と描画がWebGLだけで完結する。

考え方のイメージは以下の通り。

- 経緯線の間隔ごと（例えば10度ごと）に色を塗り分けた緯度経度座標系上の画像を生成する。
- 生成した画像に正距方位図法の投影変換を適用する。
- 投影変換された画像に対し、LaplacianフィルタやSobelフィルタなどを用いてエッジを検出し、それを元に経緯線として描画する。

但し実際には内部では画像は生成しておらず、色を塗り分けるための関数と投影変換の処理を直接使用して線を求めている。画像の投影変換と同じような処理となるため、逆方向の投影変換を使用することとなる。

実際には、経度±180度付近での不連続性などへの対応などの細かい調整も必要となる。

## 実装例
正距方位図法の場合の実装例は以下の通り。

- ソースコード
 - https://github.com/tomosn/simple-raster-projection/blob/master/graticule-aeqd.html
- 表示例
 - [経緯線のみの場合](https://tomosn.github.io/simple-raster-projection/graticule-aeqd.html)
 - [画像付きの場合](https://tomosn.github.io/simple-raster-projection/map-aeqd.html)

※ 画像付きの場合については20度間隔に設定。

## 評価
以前の方法と比較し、以下のような利点あり。

- パフォーマンスの改善。特にスマホからの表示時のパフォーマンスが大幅に改善。
- 外周部（対蹠点）付近でも特別な処理なしに描画可能。
 - 外周部（対蹠点）付近に特化した処理（線の反対側への飛びなどへの対応）も不要となった。
 - 外周部付近では経緯線の描画自体を抑制する、というような対応も不要。
- 他の投影図法でも逆方向の変換さえあれば大きな変更なしで対応できる可能性が高い。
 - 点列を生成して描画する方法の場合、対蹠点の扱いや周期性の扱いなどで図法ごとの調整が必要な場合があった。
- JavaScript側の処理の大幅な削減。

一方で以下のような課題あり。

- 線の滑らかさの問題。
 - 投影変換に基づく大きな変化に対しては今回の方法に利点あり。
 - 但し、エッジ検出の方法に基づくピクセル単位での粗さへの対応が課題。
- 線の濃淡の調整方法の問題。


## 他の投影図法
他の投影図法でもこの方法は適用可能と思われる。
少なくとも、以下の投影図法でも同じ方法で描画可能。

### ランベルト正積方位図法
- ソースコード
 - https://github.com/tomosn/simple-raster-projection/blob/master/graticule-laea.html
- 表示例
 - [経緯線のみの場合](https://tomosn.github.io/simple-raster-projection/graticule-laea.html)
 - [画像付きの場合](https://tomosn.github.io/simple-raster-projection/map-laea.html)

### 横メルカトル図法
- ソースコード
 - https://github.com/tomosn/simple-raster-projection/blob/master/graticule-tmerc.html
- 表示例
 - [経緯線のみの場合](https://tomosn.github.io/simple-raster-projection/graticule-tmerc.html)
 - [画像付きの場合](https://tomosn.github.io/simple-raster-projection/map-tmerc.html)

# 参照

- [wgkd.org laplacian フィルタ](https://wgld.org/d/webgl/w056.html)
UITabBarItemのiconにオリジナルな画像を設定する方法（ノンコード）

# はじめに
- ノンコードです。
- AssetsCatalogを利用します。

# できること
- アイコンを単色塗りつぶしではない画像オリジナルな状態で表示できます。

#やりかた
- Sampleとしてプロジェクト作成時に利用できるTabbed App(テンプレ)を利用しています。

1. Assets.xccasetsファイルを開きます。(以降InspectorはAttribute　Inspectorに設定)
<img width="1149" alt="スクリーンショット 2019-02-11 19.08.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/103494/723f0095-1bdc-445a-90f7-3e27f40de4ff.png">

2. Firstを選択し、Attributes Inspector内の「Render　As」をDefaultから「Original　Image」に変更します。**★1**

<img width="1127" alt="スクリーンショット 2019-02-11 20.00.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/103494/eeb1bb6a-f22a-5185-31e4-f357e801a1a2.png">
3. Main.StoryBoardを開いてFirst　View　Controllerを確認すると以下のようになっていれば設定OKです。

|First　View　Controller|　Second View Controller（未変更）|
|:-----------------:|:------------------:|
| <img width="334" alt="スクリーンショット 2019-02-11 19.19.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/103494/6ed7cb42-6baf-6058-b4f3-370984b0ba36.png">            | <img width="339" alt="スクリーンショット 2019-02-11 19.19.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/103494/901ff242-97f9-62c4-7c62-77b0a031c9b4.png"> |


# ★1 で何をしたか
FirstのImageに対してUIImageのプロパティrenderingModeに.alwaysOriginalを設定した状態にしました。
コードでも設定できます。リファレンスを参考にしてください。

公式リファレンス
withRenderingMode
https://developer.apple.com/documentation/uikit/uiimage/1624153-withrenderingmode
RenderingMode
https://developer.apple.com/documentation/uikit/uiimage/renderingmode

# まとめ
この方法は、UINavigationBarItemのアイコンなど、単色で塗りつぶされてしまう箇所で利用可能です。
UITabBarItemのアイコンについては動的に変える必要がない場合等、この方法で静的に設定する方が良いと思います。
また、「画像をTabのアイコンに設定したい」というオーダー時は選択時の画像も合わせて用意してもらいましょう。
選択時の画像の設定もStoryBoardから設定可能で、TabBarItemのSelected Imageで設定可能です。
macOS上でRaspbianのイメージを編集する 出来なかったので別の方法で

# 概要
[前回](https://qiita.com/yshr1982/items/cea6435f80290a52c388)でRaspbian.imgを編集するためにmacOS上でマウントする方法を紹介した。
しかし、目的である編集する権限は得られずread onlyのままであった。ext4fuseの仕様だと思われる。
＊軽くググっただけで、深く調べていないので単なる思い込みかもしれない。

そのためmacOS上でマウントすることを諦めて別の方法で編集することにした

# 別の方法
macOS上に仮想OSのubuntuをインストールしてloop deviceを使ってイメージをマウントする方法があるのでその方法をメモする


# Raspbianイメージのパーティション構成を調べる  

```sh:image_partition
#fdisk -u -l raspbian-stretch-lite.img
Disk raspbian-stretch-lite.img: 1.8 GiB, 1866465280 bytes, 3645440 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x7ee80803

デバイス                   起動 Start 最後から セクタ  Size Id タイプ
raspbian-stretch-lite.img1       8192    98045   89854 43.9M  c W95 FAT32 (LBA)
raspbian-stretch-lite.img2      98304  3645439 3547136  1.7G 83 Linux  

```

bootイメージはFAT32で8192セクターから、root file sytem領域は98304セクターから。パーティション構成がこのコマンドで分かる。

# イメージをマウントする  

./raspberry_bootと./raspberry_kernelにbootイメージ、root file systemイメージをマウントする
loop deviceとしてデバイスを割り当てる  

```sh:loop_device.sh
#losetup -f raspbian-stretch-lite.img  
#losetup -l  
/dev/loop0         0        0         0  0 raspbian-stretch-lite.img  
/dev/loop1         0  4194304         1  0 /dev/loop0  
/dev/loop2         0 50331648         1  0 /dev/loop0  
　　　　　
```
　　
loop0にイメージがマウントされていることを確認。合わせてパーティションそれぞれにloop1とloop2がマウントされている。

```sh:mount_image
#mount -o loop,offset=4194304 /dev/loop0 ./raspbian_boot
#mount -o loop,offset=50331648 /dev/loop0 ./raspbian_kernel
試してないけど多分以下でもいける
#mount -o loop /dev/loop1 ./raspbian_boot
#mount -o loop /dev/loop2 ./raspbian_kernel
```

あとはraspbian_bootやraspbian_kernelの中身を好きに書き換えればよろし
PHPでエラーメッセージを表示する

PHPは、初期設定の状態では、エラーメッセージが表示されないことを初めて知りました。

エラーメッセージを表示するには、レンタルサーバーのWebサイトの設定画面で、php.iniの設定方法を変更する必要があります。

ロリポップの例：
https://lolipop.jp/manual/user/php-setting/
herokuでムームードメインの独自ドメインを設定する

# 一言で

* ドメインはムームードメイン取得
* herokuのhobbyプラン
* www.で設定
* SSL

上記の条件で独自ドメインを設定する

# SSLの設定

「Settings」→「Domains and certificates」→「Configure SSL」→「Automatically」

これだけでSSL設定に

# ムームードメイン側の設定

* サブドメイン：www
* 種別：CNAME
* 内容：www.独自ドメイン.herokudns.com

# ターミナル

```
heroku domains:add www.example.com
```

ターミナルで上記をうってドメイン追加。ターミナルからじゃなくてconsoleからadd domainでもok。

# エラー対処

## カスタムドメインがwww.サービスドメイン.herokudns.comにならない

herokuの仕様変更かわからないけどカスタムドメインがadddomain時に自動でついてそれが「www.サービスドメイン.herokudns.com」じゃなかった。ムームードメインの方をその自動でついたものに変更したら通った。
TikZ 3次元プロット(3d plot)

#TikZで3次元プロットをする
$\def\fraction(#1/#2){\frac{#1}{#2}}$ $\def\bunsu(#1/#2){\frac{\,#1\,}{\,#2\,}}$ $\def\DIS{\displaystyle}$ $\def\unisq{\mathrm{cm^2}}$ $\def\unicube{\mathrm{cm^3}}$ $\def\defsym{\overset{\rm def}{=}}$ $\def\subsym{\overleftarrow{\rm sub}}$
## パッケージ

https://latex.net/tikz-3dplot/

`\usepackage{tikz-3dplot}`

## 描画

カメラアングルを天頂角$\theta$（90-緯度）と方位角$\phi$で書くことができます。

`\begin{tikzpicture}`の前に，`\tdplotsetmaincoords{天頂角}{方位角}`を書きます。ただし，方位角$\phi$は$y$軸負の方向から取ります。角度は度数法で書きます。数値の積の形，分数の形でも書くことができます。

`\begin{tikzpicture}`のオプションに`tdplot_main_coords`を入れます。



```tex
\tdplotsetmaincoords{#実数1}{#実数2}
\begin{tikzpicture}[tdplot_main_coords]
.
.
.
\end{tikzpicture}
```

`\tdplotsetmaincoords{#実数1}{#実数2}`

`#実数1`, `#実数2`は3次元空間内のカメラの位置を表現しています。
`#実数1`はz軸から傾いた角度，`#実数2`はz軸まわりに回転した角度を意味している。~~ただし，`#実数2`はy軸からx軸への回転角（時計回り）になるため，注意が必要。~~


### 例
`\tdplotsetmaincoords{60}{125}`
z軸から60°，z軸まわりに125°回転させたという意味。


`\tdplotsetmaincoords{0}{0}`
x-y平面が，横軸x・縦軸yの形で見える（通常通り）。


## 座標の記述
座標は3つの数値の組`(#実数1,#実数2,#実数3)`で記述します。`(#実数1,#実数2)`と記述されているものは，`(#実数1,#実数2,0)`と解釈されると思う。


## 重なり順
描画される図形の重なる順番は，後の行ほど手前になる。3次元的な位置関係の重なり順は意味をもたない。


## クリップ (clip)

以前，カメラの天頂角，方位角を使って座標を回転させて，いつも一定の形のclipをしていましたが，`tikz-3dplot`に備わった機能がありました。

`tdplot_screen_coords`

オプションに`tdplot_screen_coords`と書いておくと，デフォルトのカメラアングルの座標を書くことができます。切り抜きのコマンドに使用する場合は，

```tex
\clip [tdplot_screen_coords] (-4,-4,0) rectangle (4,4,0);
```
と書くと，正面を向いている長方形になります。


### カメラ位置の回転角（没）

`\tikzmath`

$\phi \defsym 0$

$\delta \defsym $ 0

$\theta \defsym 90 - \delta$



$\delta $：z軸からの角度 緯度の反対の取り方



%3次元プロットの記述

\tdplotsetmaincoords{ $\delta$ }{ $\phi$ } 

\begin{tikzpicture}[tdplot_main_coords]

...

\end{tikzpicture}


3次元プロットを使用した場合，`\clip`で指定した座標が3次元の座標として指定されるので，角度がついてしまいます。

カメラの向きに合わせてクリップしたい場合もあります。そんな場合は，一度座標を指定して，それを回転させてからクリップで指定しましょう。


### クリップする座標の変換

初期値の代入

`\tikzmath`

```math
\begin{pmatrix}
x\\
y\\
z
\end{pmatrix} \subsym
\begin{pmatrix}
C_x^{max}\\
0\\
C_z^{max}
\end{pmatrix}
```


yz平面の回転

`\tikzmath`

```math
\begin{pmatrix}
x\\
y\\
z
\end{pmatrix} \subsym
\begin{pmatrix}
x\\
\cos (-\theta) y - \sin (-\theta) z\\
\sin (-\theta) y + \cos (-\theta) z
\end{pmatrix}
```



xy平面の回転

`\tikzmath`

```math
\begin{pmatrix}
x\\
y\\
z
\end{pmatrix} \subsym
\begin{pmatrix}
\cos (\phi) x - \sin (\phi) y\\
\sin (\phi) x + \cos (\phi) y\\
z
\end{pmatrix}
```
vagrantでCyberduckに接続

#はじめに
Qiitaに記事を書くのは初めてです。vagrantでCyberduckに接続するやり方で詰まったので個人用として書きます。やり方はあっていると思います。
#開発環境&前提
+ macOS
+ CentOS7.6(vagrant+VirtualBox)
+ Cyberduckインストール

#ターミナルでの作業
まずターミナルを開いて、`$vagrant up`をしてください(サーバー起動)。サーバーが起動したら`Vagrantfile`のディレクトリに移動して、
`$vagrant ssh-config`を実行する。そうすると下記のようにでます。

```
Host default
  HostName 127.0.0.1
  User vagrant
  Port 2222
  UserKnownHostsFile /dev/null
  StrictHostKeyChecking no
  PasswordAuthentication no
  IdentityFile /Users/username/vagrant/MyCentOS/.vagrant/machines/default/virtualbox/private_key
  IdentitiesOnly yes
  LogLevel FATAL
```

これらの内容は記録しといてください。そうしたらCyberduckに移動してください。

#Cyberduckでの作業
Cyberduckに移動したら左上にある新規作成を押します。今回はプロトコルをSFTP　(SSHによる暗号化 FTP)にします。
<img width="461" alt="スクリーンショット 2019-02-11 13.36.18.png" src="https://qiita-image-store.s3.amazonaws.com/0/346938/bf21bab5-563b-d5c6-cca0-85ab702a7b84.png">

あとはサーバ、ポート、ユーザー名、パスワードをしてすれば接続できます。そこで`$vagrant ssh-config`を実行内容を使います。

+ HostName = サーバ(127.0.0.1)
+ Port = ポート(2222)
+ User = ユーザー名(vagrant)

サーバ、ポート、ユーザー名このようになります。で、パスワードもユーザー名と同じように

+ パスワード = vagrant

になるはずです。それで接続できれば大丈夫です。だけど接続できないときもあります。

#接続できなければ
接続できなければ`SSH Private Key`で`IdentityFile`を指定すれば接続できるはずです。

```
/Users/username/vagrant/MyCentOS/.vagrant/machines/default/virtualbox/private_key
```
途中のファイルから隠しフォルダ内にあるので`Command + Shift + G`でファイルを指定してください。
<img width="498" alt="スクリーンショット 2019-02-11 19.20.20.png" src="https://qiita-image-store.s3.amazonaws.com/0/346938/af43ca52-e70c-bd42-ad0e-0aee0ba7f245.png">
これで接続できるはずです。
<img width="598" alt="スクリーンショット 2019-02-11 18.00.46.png" src="https://qiita-image-store.s3.amazonaws.com/0/346938/8f50df8b-1805-9118-90cb-6b3e02c65513.png">
このような画面になれば成功です。

#まとめ
同じような記事はあると思いますけど初心者がわかるような記事になるように、なりより自分が次にした時にすぐ理解できるように書きました。

#参考サイト
+ [Vagrantで作成したローカルサーバにFTPクライアント(Cyberduck)からログインできないときの解決法](https://qiita.com/noraworld/items/a0fac559d2d6e76d50f8)
+ [【ローカル開発環境】VagrantでCyberduckに接続するまでの流れ](https://qiita.com/wavy/items/3edb8ebfebfb8f321842)
letsencrypt-nginx-proxy-companionを使って複数ドメイン名に無料SSL証明書を適用する

# 初めに

Docker Compose等で
* [nginx-proxy](https://github.com/jwilder/nginx-proxy)
* [letsencrypt-nginx-proxy-companion](https://github.com/JrCs/docker-letsencrypt-nginx-proxy-companion)
を利用すると自作サービスのコンテナにLet’s EncryptのSSL証明書を適用して公開する事が可能。[^1]


単一のコンテナへ以下の様な複数ドメイン名に対してSSL証明書を適用する方法を調査した。
<pre>
example.com
www.example.com
</pre>

#結論

利用ドメイン名を指定する環境変数をカンマ区切りで記述すると適用してくれる。[^2]

- 自作サービス側のdocker-compose.yml例

```yaml
version: '3.3'
services:
  myapp:
    image: my-app
    environment:
      VIRTUAL_HOST: example.com,www.example.com # ←　カンマ区切り指定
      LETSENCRYPT_HOST: example.com,www.example.com # ←　カンマ区切り指定
      LETSENCRYPT_EMAIL: mail@example.com

networks:
  default:
    external:
      name: shared
```

- nginx側のdocker-compose.yml例

```yaml
version: "2"
services:
  nginx-proxy:
    image: jwilder/nginx-proxy
    container_name: nginx-proxy
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - /var/run/docker.sock:/tmp/docker.sock:ro
      - ./certs:/etc/nginx/certs:ro
      - /etc/nginx/vhost.d
      - /usr/share/nginx/html
    restart: always
    networks:
      - shared
        
  letsencrypt:
    image: jrcs/letsencrypt-nginx-proxy-companion
    container_name: letsencrypt
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - ./certs:/etc/nginx/certs:rw
    volumes_from:
      - nginx-proxy
    restart: always
    networks:
      - shared

networks:
  shared:
    external: true
```

#実行例

##事前準備

上記の様にdocker-compose.ymlを分離している場合は事前にDocker networkを作成し同じネットワークを利用する様に指定しておく必要が有る。

```bash
docker network create --driver bridge shared
```

##起動

　nginx側、自作サービスの両方を起動する

```bash
docker-compose up -d
```

##結果

指定した保存ディレクトリ内に以下の様にドメイン名別の証明書が生成される。
どちらのドメイン名でもSSL接続可能となる。

```bash
example.com.chain.pem
example.com.crt
example.com.dhparam.pem
example.com.key

www.example.com.chain.pem
www.example.com.crt
www.example.com.dhparam.pem
www.example.com.key
```


[^1]: 前提としてDNS設定済みの独自ドメインが必要です。

[^2]: 利用するドメイン名を事前に名前解決設定しておく必要有り。
正規表現入門その１

過去にブログに書いた記事の移転その２です。今回は正規表現について書いた[この記事](https://yk0807.com/larablog/posts/6)のQiitaへの移転です。

正規表現は何となくとっつきづらそうなイメージがありますが、使いこなせるようになると色々なこと（バリデーションとか）が簡単にできるようになるので便利です。

正規表現で最低限抑えることは、何と言っても**「メタ文字」**に尽きます！！メタ文字とはその文字にある特別な意味をもたせて色々な表現の助けになるようにしたものです。 よく使われるものは、以下のものです。

**基本形**
^ 文字列（行）の始まり

$ 文字列（行）の終わり

. 任意の1文字（改行以外）を表す

| 選択肢（右側か左側のどちらか）を表す

() サブパターンの始まりと終わり

\ エスケープ文字（これ＋メタ文字でその文字自体を表すようになります）

**量指定子（ある文字が何文字とか）**
? 　0回か1回マッチするもの

* 　0回以上マッチするもの

+ 　1回以上マッチするもの

{n} n回の繰り返し

{n,} n回以上の繰り返し

{n,m} n回からm回の繰り返し

**文字クラス（幾つかの文字を選択肢として表す）**
[]　　文字クラスの始まりと終わり（[]内の1文字とマッチするものを探すのに使う）

-　　範囲を表す（[a-c]ならa,b,cのどれか）

^　　否定を表す（[^235]なら2,3,5以外）

例えば、^ap{1,3}[lr]e$なら、最初がaで始まり、pが1つから3つ続いて、次にlかrが来て、最後がeで終わります。 なので、"apple"とか、"apre"なんかがマッチします。

後は応用例として、URLの表し方を紹介します。

```
^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$
```

http、https、ftpで始まって://と続いて、アルファベット（大文字、小文字）、数字、後はいろんな記号が1つ以上続いて終わるというものです。 なので、http://yahoo.co.jp とかがヒットします。 PHPでは正規表現にマッチする関数としてpreg_matchがあって（使い方は[こちら](http://php.net/manual/ja/function.preg-match.php)をみてください）、

```PHP
preg_match('/^(https?|ftp)(:\/\/[-_.!~*\'()a-zA-Z0-9;\/?:\@&=+\$,%#]+)$/', $url);
```

みたいな使い方をします。

他にも文字列を置換したり、複数の正規表現を探したりといろんな関数があるので、是非使いこなせるようにしたいですね。その辺りは適当なタイミングで正規表現入門その２として記事を書こうと思います。
formタグのactionとheader関数によるリダイレクトの優先度

#actionとheader関数
結論からいうとaction属性が優先される
##action属性
formの中の属性。
指定したURLに送信できる。
```<form action="http://www.example.com/">
```

##header関数
header関数はHTTPヘッダを指定できる、リダイレクトに使用できる。
```header('Location: http://www.example.com/);
```

##お問い合わせフォーム
確認画面から初期画面にもどると完了画面へ移動する分岐の際リダイレクトが必要になる


###失敗例
action属性が優先されるためphpの記述でsendとbackで場合分けしているがcomplete.phpに飛ぶ

```php:comfirm.php
<?php
session_start();
    if(isset($_POST["send"])) {
        header("Location:complete.php");
    }
    elseif (isset($_POST["back"])){
        header("Location:input.php");
    }
    else{

    }
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>お問い合わせ</title>
</head>
<body>
<form  action="complete.php" method="post">
    名前<br />
    <?php echo $_SESSION["name"];?><br />
    電話番号<br />
    <?php echo $_SESSION["telNumber"];?><br />
    メールアドレス<br />
    <?php echo $_SESSION["mail"];?><br />
    <input type="submit" name="send" value="確認">
    <input type="submit" name="back" value="戻る">
</form>
</body>
</html>
```

###成功例
action属性をcomfirm.phpに変更
type属性がsubmitのinputタグが押された際phpの記述が通る。

```php:comfirm.php
<?php
session_start();
    if(isset($_POST["send"])) {
        header("Location:complete.php");
    }
    elseif (isset($_POST["back"])){
        header("Location:input.php");
    }
    else{

    }
?>
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>お問い合わせ</title>
</head>
<body>
<form  action="comfirm.php" method="post">
    名前<br />
    <?php echo $_SESSION["name"];?><br />
    電話番号<br />
    <?php echo $_SESSION["telNumber"];?><br />
    メールアドレス<br />
    <?php echo $_SESSION["mail"];?><br />
    <input type="submit" name="send" value="確認">
    <input type="submit" name="back" value="戻る">
</form>
</body>
</html>
```
RGB ↔ HSL などの色表現を変換するツールを作った

## tl;dr

- [cocore][GitHub] を作った
  - RGB ↔ HSL などの色表現を変換する CLI ツール

## cocore の紹介

[cocore][GitHub] を作った。

RGB, HSL, Hex 形式の色表現を CLI で相互変換するコマンド。

RGB `rgb(255, 0, 0)` ↔ HSL `hsl(0, 100%, 50%)` ↔ Hex `#F00`
といった感じで CSS 形式の表現を変換できる。

使用例

```console
$ cocore --to=rgb '#f00'
rgb(255, 0, 0)
$ echo 'hsl(0, 100%, 50%)' | cocore
#F00
```

## なぜ作ったか

GUI が必要なツールなどを作るとき、配色を決める際に HSL で色相かトーンを固定しつつ色を量産することが多い。
その際に HSL 形式で直接指定できれば楽だが、RGB 形式または Hex 形式でしか受け付けていないことがままある。
変換するツールはインターネットにいくらでもあるが手元でサッとやりたかったのと、ジェネレーターなどのスクリプトに組み込みたかったので。

## 使い方

バイナリファイルを実行可能にしてパスを通すだけ。
macOS ユーザーは Homebrew でインストールできる。

インストール後、ヘルプ表示。

```console
$ cocore -h
```

詳細は [GitHub][] の README で。

## 使ったツールの感想

Rust で作った。Rust 2018 Edition を試したかったので。
といってもモジュール周りが楽になった！ぐらいの使い方しかしてない。

Rust の Linter として [Clippy][] を使った。
元々 VSCode の Rust (rls) 拡張に組み込まれているようで、オプションで有効にするか `#![warn(clippy)]` を指定することで、リアルタイムでアドバイスされるようになる。しばらく気づいてなかった。

`rgb(255, 0, 0)` などの文字列をパースするために、[cssparser][] という crate を使っている。
これ Servo organization のリポジトリだ。見つけたときは興奮した。

テストとビルドのため、CircleCI を使った。
macOS と Linux 両方のバイナリを作りたかったので、TravisCI を最初試していたがローカルコマンドのために Gem のインストールを要求されて失敗したり、YAML のフォーマットが理解しにくい感じだったりといまいち感が出てきたため CircleCI にした。
が、そちらでも Rust の macOS 向けクロスコンパイルで失敗して原因がわからなかったので諦めて手元でビルドするようにした。

バイナリの配布のために GitHub Releases と Homebrew を使った。
Homebrew の Formula を作るのは今回が初。思っていたより簡単にできた。

---

`cocore` のアイデアや解決したこと自体が微妙なので記事を書いててテンションが上がらない。
作っている最中の勉強がメインの成果だった。


[GitHub]: https://github.com/KoharaKazuya/cocore
[Clippy]: https://github.com/rust-lang/rust-clippy
[cssparser]: https://github.com/servo/rust-cssparser
winapi-rsのあれこれ

特に何もなければ、winapi-rsのバージョンは`0.3.6`を前提としています。

# 基本

　C++等では`Windows.h`をインクルードするだけで`WinUser.h`などが使えるようになりますが、winapi-rsでは使いたい関数や構造体などが書かれたヘッダの名前を`features`に書く必要があります[^1]。

以下の例は、`WinUser.h`の関数等をRustで使えるようにするものです。

```toml:Cargo.toml
[dependencies]
winapi = { version = "0.3.6", features = [
    "winuser",
] }
```

クレートの名前は`winapi`です。

```rust
extern crate winapi;
```

# モジュール

　winapi-rsのモジュールはWindows KitsのIncludeフォルダと同じように`shared`や`um`で分けられています。いちいちフルパスで書くのは面倒なので例えば`HWND`を`use`でモジュール名を省略したい場合は以下のようになります。

```rust
use winapi::shared::windef::HWND;
```

# GetModuleHandle関数の例

　例えば`GetModuleHandle`関数は`WinUser.h`や`wingdi.h`ではなく`libloaderapi.h`にあるので上記の指定だけでは使えません。以下の例のように`features`に`libloaderapi`を追加`GetModuleHandle`関数が使えるようになります。

```toml:Cargo.toml
[dependencies]
winapi = { version = "0.3.6", features = [
    "winuser",
    "wingdi",
    "libloaderapi",
] }
```

# 構造体にDefaultを
　winapi-rsの`features`に`impl-default`を指定すると、すべてのメンバが0で初期化された構造体を返す`Default`トレイトが使えるようになります。

**例**

```toml:Cargo.toml
[dependencies]
winapi = { version = "0.3.6", features = [
    "impl-default",
] }
```

```rust:ソースコード
use winapi::winuser::MSG;

// msgはすべて0で初期化されています
let mut msg = MSG::default(); 
```

# ジェネリックなCOMインターフェイス

　winapi-rsには`winapi::Interface`トレイトがあり、winapi-rsにあるCOMインターフェイスはこのトレイトを実装しています。トレイト境界を`winapi::Interface`トレイトにすればジェネリックにCOMインターフェイスを扱うことができます。

**例**

　以下の例は、`CreateDXGIFactory1`関数をジェネリクスで`IDXGIFactory1`だけでなく`IDXGIFactory2`等を指定できるようにしています。

```rust
use winapi::shared::dxgi::*;
use winapi::Interface;

fn create_dxgi_factory<T: Interface>() -> Result<*mut T, HRESULT> {
    let mut obj = null_mut();
    let res = unsafe { CreateDXGIFactory1(&T::uuidof(), &mut obj) };
    if res < 0 {
        Err(res)
    } else {
        Ok(obj)
    }
}
```

```rust
use winapi::shared::dxgi1_2::*;

let dxgi_factory = create_dxgi_factory::<IDXGIFactory2>();
```

# crates.ioの代わりにGitHubのリポジトリに

　以下の例のように`git`キーでwinapi-rsのリポジトリとブランチを指定すると、最新コミットのwinapi-rsが使えます。もちろん開発中のもので安定版ではないので注意してください。

**例**

```toml:Cargo.toml
[dependencies]
winapi = { git = "https://github.com/retep998/winapi-rs", branch = "0.3", features = [
    "winuser",
    "wingdi",
] }
```

# リンク

https://github.com/retep998/winapi-rs
https://crates.io/crates/winapi

[^1]: `windef`のように`winapi-rs/build.rs`にないものは書く必要はないみたいです。
SQLをログイン不要で試せるサイト

使ったことがあるものをまとめてみました。
SQL Fiddleは、落ちてることが多いですが、他は安定してます。

#01 DB Fiddle
[https://www.db-fiddle.com/](https://www.db-fiddle.com/)

MySQL 8.0.12
PostgreSQL 12.1

#02 db<>fiddle
[https://dbfiddle.uk/](https://dbfiddle.uk/)

Oracle Database 18c Express Edition Release 18.0.0.0.0
SQLServer2019
MySQL 8.0.19
PostgreSQL 12.0

#03 rextester.com
[https://rextester.com/](https://rextester.com/)

Oracle Database 18c Express Edition Release 18.0.0.0.0
SQLServer2014
PostgreSQL 9.6.2
MySQL 5.7.12

#04 SQL Fiddle
[http://sqlfiddle.com/](http://sqlfiddle.com/)

Oracle Database 11g Express Edition Release 11.2.0.2.0
SQLServer2017
PostgreSQL 9.6
MySQL 5.6.39
Material Component LibraryのMaterialButtonのtextAllCapsをテーマで変更する

AppCompatButton同様、MaterialButtonもデフォルトでは `textAllCaps="true"`で全て大文字で表示されます。

AppCompatButtonの場合は、以下のようにテーマを指定すれば小文字にすることができました。

```xml
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
    <item name="buttonStyle">@style/AppButton</item>
</style>

<style name="AppButton" parent="Widget.AppCompat.Button">
    <item name="android:textAllCaps">false</item>
</style>
```

MaterialButtonの場合は、指定する属性が少し変わるので注意が必要です。
具体的には、`materialButtonStyle` という新しい属性を指定します。

```xml
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
    <!-- buttonStyleではなくmaterialButtonStyleを指定すること -->
    <item name="materialButtonStyle">@style/AppButton</item>
</style>

<style name="AppButton" parent="Widget.MaterialComponents.Button">
    <!-- MaterialComponentで定義された属性を指定するのでandroid:は不要 -->
    <item name="textAllCaps">false</item>
</style>
```

以上です。
RedmineをAnsible playbookでインストール中にBundlerエラー(Ubuntu 16.04)

#1 環境
Redmine 3.4.8 stable
Ubuntu 16.04.5 LTS
PostgreSQL 9.5

#2 Ansible playbookで簡単インストール
ちょっとしたHWトラブルで、OSから含め何度もクリーン環境を作ることがあったのですが、公式サイトで公開されているAnsible playbookを使うと、数ステップでインストール完了するのでとても楽です。
http://redmine.jp/install/
https://github.com/farend/redmine-ubuntu-ansible

実施手順などは、上記の説明に従って進めてください。
先人の方々に本当に感謝ですね。


#3 インストールがこけた・・・
さて、Ansible playbookでインストールを進めていきます。

```
$ ansible-playbook -K -i hosts site.yml
```
すると、gemsパッケージのインストールのところで失敗し止まってしまいました。
(2019/02/11時点です、今後改善されるかもしれません)

```ruby:インストール中のエラーログ
(省略)
fatal: [localhost]: FAILED! => {"changed": true, "cmd": ["bundle", "install", "--path", "vendor/bundle"], "delta": "0:00:02.892941", 
(省略)
 bundler (< 2.0.0, >= 1.5.0)\n\n  Current Bundler version:\n    bundler (2.0.1)\nThis Gemfile requires a different version of Bundler.\nPerhaps you need to update Bundler by running `gem install bundler`?\n\nCould not find gem 'bundler (< 2.0.0, >= 1.5.0)' in any of the relevant sources:\n  
(省略)
localhost                  : ok=23   changed=18   unreachable=0    failed=1   
```

どうやら、bundlerのバージョンが要件(2.0.0よりも前、1.5.0以上)に合っていないため、エラーで止まってしまったようです。

#4 Bundlerのバージョン確認と、旧バージョンを指定して入れ直し
bundlerが新しいものが入ってしまっていたようです。

```
$ bundler -v
Bundler version 2.0.1
```
インストール可能なバージョンの一覧をチェックしてみます。

```
$ gem search ^bundler$ --all

*** REMOTE GEMS ***

bundler (2.0.1, 2.0.0, 1.17.3, 1.17.2, 1.17.1, 1.17.0, 1.16.6, (長いので省略)
```
今回は、1.17.3がちょうど都合が良さそうなので、こちらに入れ替えてみます。

```
$ sudo gem uninstall bundler
$ sudo gem install bundler -v 1.17.3 --no-rdoc --no-ri
```
これでAnsible playbookを再実行して、無事インストール完了です。
anyenv 経由の rbenv をアップデートする

```sh
$ cd ~/.anyenv/envs/rbenv
$ git pull origin master
$ cd ./plugins/ruby-build
$ git pull origin master
$ rbenv install -l
```

とすると、最新版の Ruby がインストールリストに表示されるのでインストールする。

## anyenv 経由での *env を一括でアップデートする

こういうこともできるみたい。

```
$ anyenv update
```

こっちのほうが簡単でいいですね。anyenv 便利だわー。
ps aux でコマンドだけソートして表示したい

# 目的
psで実行プロセス一覧を見た時、とりあえずソートして似たプロセスがどのぐらい実行しているか確認したかった。

# 方法

```
ps aux | awk '{for(i=1;i<=10;i++){$i=""}; print $0}' | grep -v -e "^COMMAND$" | sort
```
awkでは`$i=""`とすることで、i番目の列は非表示にする、ということが可能。これを利用した。


# 結果
長いので一部省略

```
          (uname)
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          -zsh
          /Applications/ActivityTimer.app/Contents/MacOS/ActivityTimer
          /Applications/Alfred 3.app/Contents/MacOS/Alfred 3
          /Applications/Backup and Sync.app/Contents/MacOS/Backup and Sync
          /Applications/Backup and Sync.app/Contents/PlugIns/FinderSyncAPIExtension.appex/Contents/MacOS/FinderSyncAPIExtension
          /Applications/Clipy.app/Contents/MacOS/Clipy
          /Applications/Docker.app/Contents/MacOS/Docker
          /Applications/Docker.app/Contents/MacOS/com.docker.supervisor -watchdog fd:0
          /Applications/Google Chrome.app/Contents/MacOS/Google Chrome
          /Applications/Google Chrome.app/Contents/Versions/71.0.3578.98/Google Chrome Framework.framework/Helpers/crashpad_handler --monitor-self-annotation=ptype=crashpad-handler --database=/Users/koishi/Library/Application Support/Google/Chrome/Crashpad --metrics-dir=/Users/koishi/Library/Application Support/Google/Chrome --url=https://clients2.google.com/cr/report --annotation=channel= --annotation=plat=OS X --annotation=prod=Chrome_Mac --annotation=ver=71.0.3578.98 --handshake-fd=8
```

# 参考
[linux - Using awk to print all columns from the nth to the last - Stack Overflow](https://stackoverflow.com/questions/2961635/using-awk-to-print-all-columns-from-the-nth-to-the-last/2961994)
WindowsサーバでRDPを複数ポートで受け付ける

## Intro

あるWindowsサーバに対して、

* 社内NWのポート制限などの事情により、デフォルトの3389番ポート以外のポートでRDP接続したい
* 一方で、すでに3389番ポートで接続できているユーザに対して影響を与えたくない

といった事情により、複数ポートでRDP接続を受け付けたい場合があります。
ググって出てくる日本語の記事類だと「RDPのポート変更」について記載されたものはありますが、これでは2番目の要求事項を満たすことはできません。
StackExchangeで参考になるQ&Aを見つけたので、これをベースにしつつ以下の方法でできることを確認しました。

**注：本記事の内容を参考にしてRDP接続変更を行った際の設定失敗による接続不可や、あなたの会社の情シス部門・セキュリティ監査部門との関係について一切の責任を負いません。自己責任でお願いいたします。**

## やること

* `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp`をコピーして`HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp-XXX` (XXX : 任意の名称)を作成
* `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp-XXX\PortNumber` の値を、新たに受け付けたいポート番号に変更する
* Windowsファイアウォールの設定で、当該ポートのインバウンド接続を許可するルールを追加する

あとは、AWS上のサーバであればセキュリティグループやNACLの許可等も適宜。

## コマンド例 : 443番ポートを新たに開けたい場合

### レジストリのコピーとポート番号変更

Windows Server 2016 Datacenterにて動作確認しました。

```powershell
# レジストリのコピー
REG COPY "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp-443" /s
# コピー先のレジストリキー上でポート番号変更。 0x1bbのところはポート番号の16進数表記
REG ADD "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp-443" /v PortNumber /t REG_DWORD /d 0x1bb /f`
# ファイアウォールの許可ルール追加 : 参考記事[2]より
New-NetFirewallRule `
        -Name Open-Port-443 `
        -DisplayName Open-Port-443 `
        -Description "Open-Port-443" `
        -Enabled True `
        -Profile Any `
        -Direction Inbound `
        -Action Allow `
        -EdgeTraversalPolicy Block `
        -LooseSourceMapping $False `
        -LocalOnlyMapping $False `
        -OverrideBlockRules $False `
        -Program Any `
        -LocalAddress Any `
        -RemoteAddress Any `
        -Protocol TCP `
        -LocalPort 443 `
        -RemotePort Any `
        -LocalUser Any `
        -RemoteUser Any 
```

## 参考記事

1. [Remote Desktop listen on 2 different ports - Server Fault](https://serverfault.com/questions/528639/remote-desktop-listen-on-2-different-ports)
2. [EC2 Windowsインスタンスに22番ポートでRDP接続するためのUserData - Qiita](https://qiita.com/c9katayama/items/7dc9a1f64b59a98af6c1)