OmniAICreator/Qiita-1.07M huggingface dataset:
CakePHPのMigrationクラスを既存のクラス定義からジェネレートする

既存のクラス定義からCakePHP3のマイグレーションを生成するジェネレータを作った。

プロパティが沢山あるクラスを作ってからマイグレーションクラスの叩き台を作ったりする時に使えると思う。

## ジェネレータクラス

```php

<?php

class MigratinoClassGenerator
{
  public function generate(string $className)
  {
    $ref = new ReflectionClass($className);
    $properties = $ref->getProperties();
    
    $migrationClass = new MigrationClass();
    
    foreach ($properties as $property) {
      $migrationClass->addColumn($property->getName());
    }
    
    return $migrationClass->generate($ref->getName());
  }
}

class MigrationClass
{
  private $columns = [];
  
  public function addColumn(string $name, $type = 'string')
  {
    $this->columns[] = [
      'name' => $name,
      'type' => $type,
    ];
  }
  
  public function generate(string $className)
  {
    $buf = [];
    
    $buf[] = '<?php';
    $buf[] = '';
    $buf[] = 'use Migrations\AbstractMigration;';
    $buf[] = '';
    $buf[] = 'class CreateProduct extends AbstractMigration';
    $buf[] = '{';
    $buf[] = '    public function up()';
    $buf[] = '    {';

    $tableName = strtolower($className);
    $buf[] = sprintf('        $this->table(\'%s\')', $tableName);
    
    foreach ($this->columns as $column) {
      $buf[] = $this->generateColumn($column);
    }
    
    $buf[] = '            ->create();';
    $buf[] = '    }';
    $buf[] = '';
    $buf[] = '    public function down()';
    $buf[] = '    {';
    $buf[] = '        $this->dropTable(\''. $tableName . '\');';
    $buf[] = '    }';
    $buf[] = '}';

    return join("\n", $buf);
  }
  
  private function generateColumn(array $column)
  {
    $template = <<<TPL
            ->addColumn('%s', 'string', [
                'default' => null,
                'limit'   => null,
                'null'    => false,
            ])
TPL;

    return sprintf($template, $this->camelCase($column['name']));
  }
  
  private function camelCase(string $input) {
    preg_match_all('!([A-Z][A-Z0-9]*(?=$|[A-Z][a-z0-9])|[A-Za-z][a-z0-9]+)!',
                   $input,
                   $matches);
                  
    $ret = $matches[0];
    foreach ($ret as &$match) {
      $match = $match == strtoupper($match) ? strtolower($match) : lcfirst($match);
    }
    
    return implode('_', $ret);
  }
}
```

## 実行方法

```php
<?php

$g = new MigratinoClassGenerator();
echo $g->generate('Product'); // クラス名を指定する
```

## 出力結果

```php
<?php

use Migrations\AbstractMigration;

class CreateProduct extends AbstractMigration
{
    public function up()
    {
        $this->table('product')
            ->addColumn('id', 'string', [
                'default' => null,
                'limit'   => null,
                'null'    => false,
            ])
            ->addColumn('code', 'string', [
                'default' => null,
                'limit'   => null,
                'null'    => false,
            ])
            ->create();
    }

    public function down()
    {
        $this->dropTable('product');
    }
}
```
WindowsバッチでCSVファイルを読み込む

#突然のWindowsバッチ
業務にてバッチファイルを組むことになり、あちらこちら調べ回る羽目になったので備忘録代わりに書き起こしておく。

#やりたいこと
カンマ区切りのファイルから1行ずつ読み込んでjavaに渡す引数にする。

読み込むファイルは以下。

```csv:hoge.csv
# a,b,c,d,f,g,h,i,j,k,l
# a日本語名,b日本語名...(省略)
1,12345,4,3,2,1,1,1
2,12346,4,3,2,1,1,1,1,0,0
#3,12347,4,3,2,1,1,1,1,0,0
```
要は#の行はコメントで読みたくない。

#やったこと
実際に組んだbatファイルの内容は以下。

```bat:hoge.bat
:FileRead
REM FOR文でCSVファイルを読み込む
FOR /F "eol=# tokens=1-11 delims=," %%i IN (hoge.csv) DO (
	java -classpath . hogePackage.HogeClass %%i %%j %%k %%l %%m %%n %%o %%p %%q %%r %%s
)
```
内容はこんな感じ
・読みたくない行をeol=#で指定。
・tokensはそのまんま。1番目の値から11番目の値を使う。
・delimsは区切り文字を指定。今回はカンマ区切りなのでdelims=,を指定。いろいろ応用できるみたいだけど今回はスルー。
・ファイル名の指定は今回は相対パスで指定。
・javaに渡す引数にはiからsまで11個の値を指定。これは連続していないといけないみたい。

#とりあえず動いたので打ち止め
今回はかなりイレギュラーな対応だったため、動いた時点で終了。
ただ、今後も必要になりそうなので勉強が必要かな。
synology製NAS DS916+でファイルアクセスログ



NASのエンタープライズ利用で、ログを残す要件があるときに。

ログセンターから、ファイルアクセスのログをexportできるけれど、いちいち手動でDLするのがダルい。
ので自動化。


```
sqlite3 /var/log/synolog/.SMBXFERDB
select * from logs;
```

で閲覧可能なことがわかったので、

```
sqlite3 /var/log/synolog/.SMBXFERDB <<END >/volume1/hoge/log.txt
select datetime(time,'unixepoch','+9 hours'),username,ip,cmd,filename from logs where filename like "/fuga/%";
```
をタスクスケジューラに登録して、終わり。



/var/logだったけど、不可視ファイルってのにハマった。
フォーラムにも載ってない気がするし。
Visual Studio | WPF > マウス左クリック + Shift (またはAltキー)を検知 > Keyboard.IsKeyDown | Key.LeftShift  | Key.LeftAlt

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

### 処理概要

Buttonの押下時にShiftキーまたはAltキーを検知する。

### 参考

https://stackoverflow.com/questions/5750722/how-to-detect-modifier-key-states-in-wpf

### プロジェクト設定

[Visual Studio / WPF > WindowsアプリケーションにてSystem.Console.WriteLine()をコンソールに出力する](https://qiita.com/7of9/items/66b78fa9ad8510d52712)

### code

```MainWindow.xaml
<Window x:Class="_171110_t1439_shiftKey.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_171110_t1439_shiftKey"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Width="120" Height="30" Content="Return fire!" Click="Button_Click"/>
    </Grid>
</Window>
```

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _171110_t1439_shiftKey
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (Keyboard.IsKeyDown(Key.LeftShift))
            {
                System.Console.WriteLine("PHOTON TOPEDO!");
            }
            else if (Keyboard.IsKeyDown(Key.LeftAlt))
            {
                System.Console.WriteLine("Alert: Self-destruct sequence is activated.");
            }
            else {
                System.Console.WriteLine("photon topede");
            }
        }
    }
}
```

### 結果

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/881eeddf-77a9-a3fa-5450-cca9fb881ed4.png)

上から順番に、

- 左Shiftを押しながら
- 左Altを押しながら
- 何も押さず

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/10259052-0f73-717e-d455-56c71166cdf0.png)


技術英語

- return fire!: 「打ち返せ」
- PHOTON TOPEDE: (光子)魚雷
- Self-destruct sequence: 自爆シーケンス

### 検索用キーワード

(C++ Builderで使うもの)

- ssAlt
- ssShift
Mac にインストールされた同じバンドル ID のアプリケーションのフルパスを Terminal ＆ AppleScript で取得する方法


## 概要
友人に「Mac にインストールされた同じバンドル ID のアプリケーションのフルパスを AppleScipt で取得する方法」を聞かれていたのを思い出してググったら、Terminal でできることがわかったので、メモとして残しておく。

## Terminal で取得する方法
Terminal を起動してコマンド入力。
サンプルでは Adobe Illustrator のバンドル ID である「com.adobe.illustrator」を指定している。

```bash:コマンド
$ mdfind "kMDItemCFBundleIdentifier == 'com.adobe.illustrator'"
```

```bash:結果
/Applications/Adobe Illustrator CC 2015.3/Adobe Illustrator.app
/Applications/Adobe Illustrator CC 2017/Adobe Illustrator.app
```

## AppleScript で取得する方法
**do shell script** を使いましょう。

```applescript:sample
tell application "Finder"
	set results to do shell script "mdfind \"kMDItemCFBundleIdentifier == 'com.adobe.illustrator'\""
	log results
end tell
```

```applescript:結果
(*/Applications/Adobe Illustrator CC 2015.3/Adobe Illustrator.app
/Applications/Adobe Illustrator CC 2017/Adobe Illustrator.app*)
```

## そもそもバンドル ID がわからないという方は
1. Application フォルダを開いて、任意のアプリケーションを選択して、コンテキストメニューを表示
2. 「パッケージの内容を表示」を選択
3. Contents フォルダの中にある Info.plist をテキストエディタなどで開く
4. 	CFBundleIdentifier を検索して、下の行にある文字列がバンドル ID なので、それを使う

```
<key>CFBundleIdentifier</key>
<string>com.adobe.illustrator</string>
```

## 参考
[Searching multiple apps with same bundle ID](https://stackoverflow.com/questions/18056177/searching-multiple-apps-with-same-bundle-id)
svnを使う

普段gitを使っているが、お仕事の都合でsvnを使わなくてはいけなくなったため、gitのコマンドと置き換えてメモ。

## svnを使う準備

#### 手順1:svnをインストールする
`$ brew install subversion`
#### 手順2:svnのリポジトリをローカルに作る
`$ mkdir svn`

## svnを使う

#### リモートのsvnプロジェクトをクローンする
(git)clone=(svn)checkout
svnリポジトリの中でコマンドを実行
`$ svn co (svnのurl)`

#### addする
(git)add = (svn) status+add
先にstatusでパスを確認する
`$ svn status`
頭に?が付いているものはまだ追加されていない編集
addする
`$ svn status add (追加したいファイルorディレクトリ)`  
なぜかうまくいかないことがあるので、その時はstatusで確認したパスをコピペするとうまくいくことがある。

#### コミットする
gitはコミット、プッシュが必要だが、svnはコミットのみでok
`$ svn ci -m'コミットメッセージ'`
画像等のオブジェクトの順番を変更する


#環境
Xcode9.1

#方法
`View Controller`のオブジェクトの順番が下にある程 前面に来るようになっているので
`前面に表示させたいオブジェクトはリスト下`に、`背面に表示させたいオブジェクトはリスト上`に入れ替えればいい

![1.png](https://qiita-image-store.s3.amazonaws.com/0/72559/642cc888-6cf4-1321-5aed-c263f9e4b7f4.png "1.png")

![2.png](https://qiita-image-store.s3.amazonaws.com/0/72559/c7b82e3a-b191-8447-7c78-a6c8106a2a96.png "2.png")
【CSS+JS】ボックス全体をリンクさせたいけれどaで囲むのはなんか嫌な場合の対処方法

# ボックス全体をリンクさせたいんだけど、h1やdivなどをaで囲むのはなんかいやだ。。というとき

```html
<div class="box link-box">
  <h2>タイトルや</h2>
  <p>内容テキストがあるブロック全体をリンク</p>
  <a href="https://qiita.com/">詳しくはこちら</a>
</div>
```
例えばこういう感じのボックスがあって、ボックス全体をクリック対象としたいとき。

divの代わりにaで囲むのが簡単ですが、それだと一部のCMSなどでは、aタグで、昔ブロック要素と言われていたタグを囲むのが、禁止されている場合とかもあり、うまくいかない場合もあります。（勝手に整形されてしまったりとか・・・）

で、jQueryを使って以下のような方法もあるかな。。と思って。

```js
jQuery(function($) {
  $('.link-box').css('cursor','pointer');
  $('.link-box').on('click',function () {
    window.location.href = $(this).find('a').attr('href');
  });
});
```

これを一つ書いておけば、`.link-box`をつけたボックスは、全体がリンク（っぽく）なり、その中にあるaタグで指定しているリンク先にジャンプします。

## サンプル

こんな感じです。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Document</title>

  <style>
  .box {
    width:30%;
    padding:15px;
    background-color:#f99;
    border:1px solid #000;
  }
  </style>
</head>
<body>

<div class="box link-box">
  <h2>タイトルや</h2>
  <p>内容テキストがあるブロック全体をリンク</p>
  <a href="https://qiita.com/">詳しくはこちら</a>
</div>

<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
jQuery(function($) {
  $('.link-box').css('cursor','pointer');
  $('.link-box').on('click',function () {
    window.location.href = $(this).find('a').attr('href');
  });
});
</script>
```

## CSSだけで実装する方法との比較

コメント欄にてCSSだけで実装する方法をご提案いただきましたので比較してみました。

### CSSだけで実装する方法
（コメント欄参照）
こちらの方法の良いところは

- JSを使わなくてよい
- ボックスにマウスオーバーしたときにステータスバーにURLがちゃんと表示される
- aタグをクリックしてのリンクになるので、aのクリックをトリガーとしたJSなどとの相性も良い。

というあたりかと思います。
個人的にはステータスバーにリンク先がちゃんと表示されるのはメリット大きいと感じました。

### JSを使って実装する方法
（上記で紹介させていただいた方法）
こちらの良いところは

- ボックスが複雑なレイアウトでも対応可能
- jQueryなのでプラグイン的に利用できる。

というところだと思います。

とくにレイアウト的な部分に関しては、CSSだけでの実装方法だと、.boxとaの間にpositionを設定した要素があるとボックス全体がリンク対象にならない場合もありそうです。
例えば、下記のような場合です。

```css
.box {
  width:30%;
  height:150px;
  padding:15px;
  background-color:#f99;
  border:1px solid #000;
  position:relative;
}
a {
  display:block;
  position:absolute;
  bottom:0px;
  right:0px;
}
a::after {
  content: "";
  display: block;
  height: 100%;
  left: 0;
  position: absolute;
  top: 0;
  width: 100%;
}
/* 詳しくはこちら　を常にボックスの右下に表示したいとき。。など。 */
```

こんな感じです。

というわけで、場合に応じて使い分けていただけたらと思います。
sed -ie "s/ho/ge/" filename は意図通りではないかもしれない

<kbd>rm -rf</kbd>
のように`-`つき一文字オプションはつなげて書けたりかけなかったりする。
sedはいろんな意味でややこしい。
<kbd>sed -ie "s/ho/ge/" filename</kbd>
は一見うまくいくが、よく見ると意図した動きにはなっていない。

# 意図通りのコマンド

<kbd>sed -i -e "s/ho/ge/" filename</kbd>

オプションをちゃんと分けて書く。


# <kbd>sed -ie "s/ho/ge/" filename</kbd>の動き

filenameは置換された内容で上書きされ、
**置換前のバックアップがfilenameeに作成される。**
filenameだけ見ていると正常に上書きされているので成功しているが、意図していないバックアップファイルが作成されている。

## `-ie`とは何か

前述の結果から予測できるでしょうが、`i`の後のファイル名を付けてバックアップをとる。
`-i.bak`などとされる。


> -i[SUFFIX], --in-place[=SUFFIX]
>    ファイルをインプレース処理で編集する (SUFFIX 指定時はバックアップを取る) 

[Man page of SED]

>-i[SUFFIX], --in-place[=SUFFIX]
>       edit files in place (makes backup if SUFFIX supplied)

,

>`$ sed -i.bak -e 's/[1１一]週間/1週間/g' dummy.txt`
>なんと、-iオプションに続いてバックアップファイルの接尾名を付けるだけ。

[sedだけでバックアップをとりつつ安全に上書き置換する - Qiita]


>```
# 上書き前のファイルに拡張子.bakをつけて保管することもできる
sed -i.bak -e '/^#/d' config.txt
```

[sedでこういう時はどう書く? - Qiita]

↑記事のコメントやらリンクをたどると結構互換性とかの話が出てきたり、バックアップのミスに一瞬気づかなかったりな小さなつまづきは案外あるのかもしれない。

[sedの-iオプションの非互換 - Qiita]

[Linux（GNU）とMac（BSD）のsedの振る舞いの違いを解決 - Qiita]


## `-ie`でなぜ正規表現の置換上書きが成功するのか

`e`がオプションではなくバックアップのサフィックスになることは理解できた。
これで変なファイルが作成された謎は解決。
だが、`-e`が無いにも関わらず正規表現の置換が出来た原因が謎である。
処理を書くなら`-e`とかしこで見た。

でももうちょっとだけちゃんと解説を読むと理解できた。

>-e、--expression、-f、または --file オプションのいずれも指定されない場合、最初のオプションでない引き数が sed スクリプトとして解釈される。残りの全ての引き数は入力ファイル名として扱われる。入力ファイルが指定されない場合は、標準入力から読み込む。 

[Man page of SED]:https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html

つまり、`-e`はスクリプトの場所を`-e`の後ろの引数だと明示するためのものであり、スクリプトを引数で使う際に必須ではないということでした。
この例ではオプションでない**最初の**引数はスクリプトになっているので、`-e`がなくても正しくスクリプトを読み込んでいたということ。

つまり…

# <kbd>sed -ei "s/ho/ge/" filename</kbd>

```
sed: -e expression #1, char 1: expected \ after `a', `c' or `i'
```

`-e`のあとの`i`がスクリプトと解釈され、構文エラー？

# <kbd>sed -e -i "s/ho/ge/" filename</kbd>

```
sed: -e expression #1, char 1: unknown command: `-'
```

`-e`のあとの`-i`がスクリプトと解釈され、構文エラー？

***

正常な
<kbd>sed -i -e</kbd>
形式のありえそうな誤表記3つのうち唯一エラーが出ず、
一見意図通り動いている形式を見事に踏み抜いて悩んでいたのか…

エラーが出ずとも、対象ファイルだけではなくディレクトリ全体を確認したり、オプションはズボらずにちゃんと書きましょう？で、教訓はいいのか…？
レアケースでいいかな？

[Man page of SED]:https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html


[sedだけでバックアップをとりつつ安全に上書き置換する - Qiita]:https://qiita.com/nagamee/items/ec81f82bbfd59c0181be

[sedでこういう時はどう書く? - Qiita]:https://qiita.com/hirohiro77/items/7fe2f68781c41777e507

[sedの-iオプションの非互換 - Qiita]:https://qiita.com/blackenedgold/items/3231c8adec40b350cf33

[Linux（GNU）とMac（BSD）のsedの振る舞いの違いを解決 - Qiita]:https://qiita.com/narumi_888/items/e425f29b84da6b72ad62
C++ Builder XE4, 10.2 Tokyo > TMutex, TCriticalSection: thread affinity | TSemaphore: not thread affinity | semaphoreでのロックコード

```txt:動作環境
C++ Builder XE4
RAD Studio 10.2 Tokyo Update 2 (追記: 2018/01/05)
```

### 関連

[C++ Builder > TMutex > { ロックされない例 | ロックされる例 } | TCriticalSection > 300msecの待ちではロックされる](https://qiita.com/7of9/items/eb3a7f2bd19e892c2b20)

### link

上記のリンクではロックが期待通りではなかった。

[stackoverflow](https://stackoverflow.com/questions/47172863/mutex-does-not-work-as-i-expected/47214224#47214224)で質問をしていたが、Remy Lebeauさんに詳細な回答をいただいた。

回答の概要
(**解釈間違いがあるかもしれません**）

- TMutex: thread affinityである
- TCriticalSection: thread affinityである
- TSemaphore: thread affinityでない
- Thread affinityの場合、TTimerでのロックはきかない
- これらより、TSemaphoreではTTimerのロックは可能
- mutexはinter-thread同期として使う
- TTimer２つではsingle threadとして動作するため、mutexはuseless
- など

### code

stackoverflowでTSemaphoreを使ったロック例を紹介いただいた。

```Unit1.cpp
//---------------------------------------------------------------------------

#include <vcl.h>
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------


HANDLE hSemaphore;


__fastcall TForm1::TForm1(TComponent* Owner)
	: TForm(Owner)
{
}

__fastcall TForm1::~TForm1()
{
    if (hSemaphore)
		CloseHandle(hSemaphore);
}

void __fastcall TForm1::FormShow(TObject *Sender)
{
    hSemaphore = CreateSemaphore(NULL, 1, 1, NULL);
    if (hSemaphore == NULL) {
        OutputDebugString(L"failed to create semaphore");
	}

    Timer1->Enabled = false;
    Timer1->Interval = 1000; // msec
    Timer1->Enabled = true;

    Timer2->Enabled = false;
	Timer2->Interval =  200; // msec
    Timer2->Enabled = true;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
        return;
    }

    if (CHK_update->Checked) {
        String msg = L"Timer1 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
        Memo1->Lines->Add(msg);
    }

    for(int loop=0; loop<10; loop++) {
        Application->ProcessMessages();
        Sleep(90); // msec
    }

	ReleaseSemaphore(hSemaphore, 1, NULL);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer2Timer(TObject *Sender)
{
    if (WaitForSingleObject(hSemaphore, 0) != WAIT_OBJECT_0) {
        return;
    }

    if (CHK_update->Checked) {
        String msg = L">>>Timer2 " + Now().FormatString(L"yyyy/mm/dd hh:nn:ss.zzz");
        Memo1->Lines->Add(msg);
    }

	ReleaseSemaphore(hSemaphore, 1, NULL);
}
//---------------------------------------------------------------------------
```

きちんとロックがかかった。
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/779d6032-6add-7477-a878-c3b9bbe98f94.png)

### 備考

mutex, critical section, semaphoreなどの機構についてはまだ学習度が浅い。
手動でUIImageをリサイズする方法

#環境
Xcode9.1

#詳細
元のUIImageのサイズが大き過ぎたので縮小しようとすると
![スクリーンショット 2017-11-10 14.12.19.png](https://qiita-image-store.s3.amazonaws.com/0/72559/a3cccab0-c4f5-65a6-e584-b96d6fd4af15.png "スクリーンショット 2017-11-10 14.12.19.png")

以下のようになってしまったので全体的に縮小するようにしたい
![スクリーンショット 2017-11-10 14.12.31.png](https://qiita-image-store.s3.amazonaws.com/0/72559/6330a0ff-2a15-4036-1d99-357e392062aa.png "スクリーンショット 2017-11-10 14.12.31.png")


#方法
`Show the Attributes inspector`->`View`->`Content Mode`で
`Aspect Fit`等を選択する

![スクリーンショット 2017-11-10 14.13.28.png](https://qiita-image-store.s3.amazonaws.com/0/72559/a6e5e5b2-039e-d32a-8787-449d1512cacb.png "スクリーンショット 2017-11-10 14.13.28.png")

![スクリーンショット 2017-11-10 14.23.23.png](https://qiita-image-store.s3.amazonaws.com/0/72559/c74af06b-4df0-c6b0-eb60-5a041bef0898.png "スクリーンショット 2017-11-10 14.23.23.png")
fluent-plugin-monologをfluentd v0.14に対応させました


## はじめに
`fluent-plugin-monolog`は、[monolog](https://seldaek.github.io/monolog/)というPHPのロガーが出力したログをパースするための`fluentd`用のプラグインです。

公開した当時の記事はこちらです。

- [fluent-plugin-monologをrubygems.orgに公開しました - Qiita](https://qiita.com/imunew/items/fe6057692a73d1fdbea3)

## issue#1
`v0.1.0`を公開したのが2016/7/7なので、1年以上経ってから[issue#1](https://github.com/imunew/fluent-plugin-monolog/issues/1)が作成されました。

実際のやりとりは、githubのissueを見てもらうとして、流れをざっと説明すると以下のようになります。

## fluent-plugin-monolog-example で動作確認 => 特に問題なさそう
`bundle exec rake test`では、動作確認としては足りないので、確認用の環境を作っていて、それが[fluent-plugin-monolog-example](https://github.com/imunew/fluent-plugin-monolog-example)なのですが、動作確認しても特に問題ありません。
期待通り動きました。

## どうやら、`fluentd v0.14`で問題あるらしい
正直、今回のissueを見るまでは、`fluentd v0.14`については何も知りませんでした。
2016年6月には遅くてもアナウンスされていたことを考えると、公開時には考慮しておくべきでした。

- [Fluentd Meetup 2016 Summer レポート 〜 v0.14 の新機能からプラグイン開発者向け API まで - 無印吉澤](http://muziyoshiz.hatenablog.com/entry/2016/06/02/001030)

上記の記事を見て、「あー。これは確かに動かないだろうな」と思いました。

## まずは、`fluent-plugin-monolog-example`の`fluentd`を`v0.14`にする
実際のPRは[こちら](https://github.com/imunew/fluent-plugin-monolog-example/pull/3)です。

```bash
curl -L http://toolbelt.treasuredata.com/sh/install-redhat-td-agent3.sh | sh
```

で、`v0.14`がインストールされます。

## 現象確認
試しに`fluentd v0.14`環境で、`fluent-plugin-monolog v0.1.8`をインストールし、ログを出力すると、下記のエラーが出ます。

```bash
# php example/fluent_handler.php 
Fluent\Logger\FluentLogger stream_socket_client(): unable to connect to tcp://127.0.0.1:24224 (Connection refused) example.fluent: {"message":"foo bar","level":"DEBUG"}
```

`fluentd`のログを確認すると、下記のようにエラーメッセージが出力されていることが分かります。

```bash
$ cat /var/log/td-agent/td-agent.log | grep error

...
#0 unexpected error error_class=NameError error="uninitialized constant Fluent::TextParser::Parser"
...
```

尚、`fluent-plugin-monolog v0.1.8`は下記のようにインストールします。

```bash
$ td-agent-gem install fluent-plugin-monolog -v 0.1.8
```

## コードとテストの修正
[fluentdの公式ガイド](https://docs.fluentd.org/v0.14/articles/plugin-update-from-v12)を見ながらコードを修正します。

- “fluent/parser”の代わりに、`“fluent/plugin/parser”`をrequireする
- スーパークラスを`Fluent::Parser`から`Fluent::Plugin::Parser`に変更

コード的には、この２つで大丈夫で、あとは、テストコードを一部、変更するだけでした。

- `Fluent::TextParser`を`Fluent::Plugin::TextParser`に変更

## 依存するfluentdのバージョンを指定
`fluentd v0.14`以上に対応していることを明示します。
ただ、色々試しましたが、インストールでエラーになるようなことはなかったので、正直、ドキュメント的な意味合いなのかと思ってます（ご存知の方ご指摘を）。

## `fluent-plugin-monolog v0.2.0`をリリース
こうして、`fluent-plugin-monolog v0.2.0`をリリースしました。

- https://rubygems.org/gems/fluent-plugin-monolog/versions/0.2.0

## おわりに
`fluentd`の`Plugins`ページでも紹介されていますので、`fluentd`と`monolog`使っている方は、`fluent-plugin-monolog`、ぜひお試しください。

https://www.fluentd.org/plugins/all#parser

ではでは。
子どもにプログラミング教育を始めるならば（独断と偏見で）コレから！

熊太郎さんの独断と偏見に基づく、プログラミング教育を始めるならばコレからー をまとめてみた(2017/11/10)

#一言でいうならば？

- ゆくゆくはプログラマやシステムエンジニアにしたいZE !! → Raspberry Pi （親の負担は超大きいけどね）
- 電気とかハードとかにも徐々に触れていってほしいなあ → Arduino （これも親の負担は大きめ）
- やっぱりゲームを……作らせたいです → プチコン （たぶん負担も低め？）
- 論理的な思考とか分かれば、プログラミングできなくてもいいよー → micro:bit 、　ヒューマンリソース、マインクラフト（ほぼなし）

ということで。Arduino使わせるならば、最低限、はんだ付けできる親であってくださいね（悪魔的スマイル）。

ただし、プチコン、マインクラフト、ヒューマンリソースはプラットフォームが「ゲーム機」になると、導入難しいかも…。という若干の懸念は残るよ！ご自宅ならば全然いいんですけどね！！

| ソリューション | micro:bit | raspberry pi | GR-SAKURA | arduino | Nintendo DS プチコン3号 | ichigoJam | PC/PS4/… マインクラフト | Switch ヒューマン・リソース・マシーン" | 
|------|------|------|------|------|------|------|------|------|------|------|
おすすめ度 | 一番おすすめ。だけどやれる事はちょっと限界あり | 何でもできる、けど、何をしようか迷うかも。 | 使いこなすまでが結構ハードル高い。 | ハード系に拘るならば有り。ソフト系的にはやや厳しい | ゲーム作りたいならばいいかも | ゲーム機買うと遊びそうならばこっちという選択肢も…？ | ゲームになっちゃいますね | これもゲーム機なので…
ブラウザ上開発 |  〇  | 〇 | 〇 | 〇 |  ×  | × | 〇 | × | 
ブロックエディタ |  〇  | 〇 | × | 〇 |  ×  | × | 〇 | 〇 | 
変数の概念 |  〇  | 〇 | 〇 | 〇 |  ◎  | 〇 | 〇 | 〇 | 
繰り返しの概念 |  〇  | 〇 | 〇 | 〇 |  ◎  | 〇 | 〇 | 〇 | 
ボタン/キー入力 |  〇  | △ | 〇 | △ |  ◎  | 〇 | 〇 | × | 
画像表示 |  △  | △ | △ | △ |  ◎  | 〇 | ？ | × | 
音楽再生 |  △  | △ | △ | △ |  ◎  | 〇 | ？ | × | 
カメラ入力 | × | △ | △ | △ | × | × | × | × | 
マイク入力 | × | △ | △ | △ | × | × | × | × | 
PC以外の初期投資 | "\3000(+部品代）" | "\4000 (+部品代）" | "\5000 (+部品代）" | "\3000  (+部品代）" | ¥500 | ￥1500 + キーボード等 | PF毎にいろいろ。\3000くらい | ¥1,000 | 
Scratch | × | 〇 | × | × | × | × | × | × | 
Ruby/mRuby | × | 〇 | 〇 | × | × | × | × | × | 
BASIC | × | × | × | × | ◎ | 〇 | × | × | 
C/C++ | × | 〇 | 〇 | 〇 | × | × | × | × | 
JavaScript  |  〇  | 〇 | × | × | × | × | × | × | 
Python  |  〇  | 〇 | × | × | × | × | × | × | 
独自 | × | × | × | × | × | × | 〇 | 〇 | 

# micro:bit
https://microbit.org/ja/

イギリスのデジタルスキルの習得を目的としたNPOが開発。

## 良い点
開発環境はブラウザを使うのでセットアップは容易だったり、実機がなくてもエミュレータが使えたりするのがとてもGOOOD!!! 

## 出来ない事
ただし、画像や音声を再生する機能がないので、ちょっとわかると「昨日が物足りない…」となる可能性もある。

#raspberry pi
https://www.raspberrypi.org/

## 良い点
Linuxなので、何でもできるよ！Scratchを動かしたり、RubyでもPythonでもなんでも動かせる！！
例えばセンサーをつけたり、カメラをつけたり、将来的にはOpenCV動かしたり、夢がめちゃくちゃ広がりますね！

## 出来ない事
技術的制約がなさ過ぎて、「何に使おう…」で埃をかぶってしまう恐れがあり。
また、ゲームの素材なども自分で集めてこないといけなかったりなど、ハードル高い。

#GR-SAKURA
http://gadget.renesas.com/ja/product/sakura.html

## 良い点
ハード改造とかも一応できる。arduinoよりも性能高いので、最適化コーディングとか気にしなくてもいい。

## 出来ない事
グラフィカルエディタがないので、「コーディングの時に誤入力でイライラ」しそう。
あと標準で表示パネルとかボタンとかないので、買ってください。

# arduino
https://www.arduino.cc/
https://www.switch-science.com/catalog/2880/

## 良い点
ブロックエディタもあるし、ハード増設もできるし、

## 出来ない事
CPU性能が低いので、効率悪いプログラム組むと厳しくなりそう。
標準でパネル・ボタンがあるのもあるので、選んで買う必要あり。

#Nintendo DS プチコン3号
http://smilebasic.com/

## 良い点
Nintendo DSを持っていれば、安価に環境構築できるよ！
ゲーム作成用の画像エディタとかもあるから、本当に「ゲーム作りたい！」っていう要望には応えやすいかも！

## 出来ない事
ハード改造はできないので、センサーつけるとかそういう方向やりたいときにはお勧めできない。

#ichigoJam
https://ichigojam.net/

## 良い点
ハード改造もできる！しかもBASIC！！これはある意味、1980年代にPC98でプログラム作ってた人にとってはありなのでは！？

#マインクラフト(PC/PS4/…)
https://www26.atwiki.jp/minecraft/

## 良い点
全世界でいろいろ使われているから、悪くはないよね！
えっと、ただしfor文だとか、世間一般でいうところのプログラミングではないので…。

#ヒューマン・リソース・マシーン(Switch)
https://ec.nintendo.com/JP/ja/titles/70010000000753

## 良い点
マインクラフトよりももっとプログラミングの概念を勉強するのに向いている！！
Switch手にはいってないから、らしいで終わってしまいますけどね！
Collection on Multi-document Summarization

# Paper List by Time

- 2014
    - [Multi-Document Summarization Using Graph-Based Iterative Ranking
Algorithms and Information Theoretical Distortion Measures](https://www.google.co.jp/url?sa=t&rct=j&q=&esrc=s&source=web&cd=8&cad=rja&uact=8&ved=0ahUKEwj3juCN1I3XAhXMoZQKHbmZDQQQFghUMAc&url=https%3A%2F%2Fwww.aaai.org%2Focs%2Findex.php%2FFLAIRS%2FFLAIRS14%2Fpaper%2Fdownload%2F7868%2F7827&usg=AOvVaw0UQ2csUQRLxDmLt9oV9Tso)


- 2013
    - [**Multi-Document Summarization using Automatic Key-Phrase Extraction**](http://www.aclweb.org/anthology/R13-2004)


- 2006
    - [Multi-Document Summarization of **Evaluative Text**](http://www.anthology.aclweb.org/E/E06/E06-1039.pdf)



- 1997
    - [Summarizing Similarities and Differences Among Related Documents]()


#SUMMARIZATION in GENERAL
- test

#CORPUS for SUMMARIZATION
- 2015
    - [BCCWJ-SUMM：『現代日本語書き言葉均衡コーパス』を
元文書とした要約文書コーパス](https://www.ninjal.ac.jp/event/specialists/project-meeting/files/JCLWorkshop_no7_papers/JCLWorkshop_No.7_34.pdf), by [浅原 正幸 (アサハラ マサユキ)](http://www.ninjal.ac.jp/organization/researcher/asaharamasayuki/), 国立国語研究所 コーパス開発センター 准教授

#PACKAGE
- 2015
    - [Shuca （朱夏）](https://github.com/hitoshin/shuca/blob/master/README.ja.md), 2015年9月7日時点では単一文書要約のみ対応
scapy dissect

scapy を使うときは関連するレイヤークラスを読み込んで使うこと。

次の例は `scapy.all` を使うので、うまく payload まで解析される。

```
from binascii import a2b_hex as fromhex
from scapy.all import Ether
pkt = Ether(fromhex("0012345678900011223344550800"
 "4500004efd4800004011f1fec0a80505c0a80502ac1f12b5003a00000800000000000500"
 "ffffffffffff0a9d0469b1540806"
 "00010800060400010a9d0469b154c0a80705000000000000c0a80702"))
```

次の例のように `Ether` だけで実行すると payload は解析されずに Raw のままになるので注意。

```
from binascii import a2b_hex as fromhex
from scapy.layers.l2 import Ether
pkt = Ether(fromhex("0012345678900011223344550800"
 "4500004efd4800004011f1fec0a80505c0a80502ac1f12b5003a00000800000000000500"
 "ffffffffffff0a9d0469b1540806"
 "00010800060400010a9d0469b154c0a80705000000000000c0a80702"))
```
[javascript]Replaceについて

javascriptを勉強始まります。
下のcodeを良く分かりません。

var text = 'abc def ghi jkl';
text.replace(/(.)\s/g,function(m0, m1){
   return ',' + m1
});
//結果：'ab,cde,fgh,ijkl'

2つ質問があります。
１．replace(/s/g,x)--"s"検索して"x"に置換しますが、/(.)\s/g は何ですか？
2.function(m0, m1){
   return ',' + m1}は何ですか？（m0: elenment? , m1:index?)
よろしくお願いします。
Oracle Database 12cの非表示列を試す

Oracle Database 12cにはSELECT * FROM table文や、SQL*PlusのDESCRIBEコマンドから列を隠す機能が提供されています。

# 非表示列
非表示列を作るには列属性にINVISIBLEを指定します。元に戻す場合はVISIBLEを指定します。

```
SQL> CREATE TABLE table1 (c1 CHAR, c2 CHAR INVISIBLE, c3 CHAR) ;

Table created.
```

INSERT文で列を省略した場合、非表示列は存在しないものとされます。

```
SQL> INSERT INTO table1 VALUES ('A', 'B', 'C') ;
INSERT INTO table1 VALUES ('A', 'B', 'C')
            *
ERROR at line 1:
ORA-00913: too many values
```

しかし、列名を指定した場合はINSERT文は成功します。

```
SQL> INSERT INTO table1(c1, c2, c3) VALUES ('A', 'B', 'C') ;

1 row created.
```
SELECT * FROM table1文を実行すると、非表示列は表示されませんが、列名をすべて指定すると表示されます。

```
SQL> SELECT * FROM table1 ;

C1 C3
-- --
A  C

SQL> SELECT c1, c2, C3 FROM table1 ;

C1 C2 C3
-- -- --
A  B  C
```

SQL*PlusのDESCRIBEコマンドからも非表示列は隠されます。ただしSET COLINVISIBLE ONを実行すると表示されるようになります。

```
SQL> DESC table1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 CHAR(1)
 C3                                                 CHAR(1)

SQL> SET COLINVISIBLE ON
SQL> DESC table1
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 CHAR(1)
 C3                                                 CHAR(1)
 C2 (INVISIBLE)                                     CHAR(1)
```

非表示列はALL_TAB_COLUMNSビューからは削除されません。しかしCOLUMN_ID列はNULLになります。

```
SQL> SET NULL NULL
SQL> SELECT COLUMN_NAME, COLUMN_ID FROM USER_TAB_COLUMNS WHERE TABLE_NAME='TABLE1' ORDER BY 2 ;

COLUMN_NAME           COLUMN_ID
-------------------- ----------
C1                            1
C3                            2
C2                   NULL

```

ALTER TABLE MODIFY文で、非表示列をVISIBLEに戻すことができます。しかし、VISIBLE指定された列は、列定義順序が最後に移動されます。

```
SQL> ALTER TABLE table1 MODIFY c2 VISIBLE ;

Table altered.

SQL> DESC table1 ;
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 CHAR(1)
 C3                                                 CHAR(1)
 C2                                                 CHAR(1)
```

正直なところこの機能が何の役に立つのかはよくわかりません。アプリケーションの更改前にあらかじめ列定義を足しておいて、更改時にVISIBLEにすることでテーブル定義の変更を高速化するくらいでしょうか。
Visual Studio | WPF > 終了処理 > shutdown | reboot > System.Diagnostics.Process.Start()

```txt:動作環境
Windows 8.1 Pro (64bit)
Microsoft Visual Studio 2017 Community
Sublime Text 2
```

### 処理概要

確認ダイアログを表示して、shutdown 処理を行う。

### 参考

https://dobon.net/vb/dotnet/system/shutdown.html#section4
の「shutdown.exeで行う」を利用しました。
(var利用に一部変更）。

[ProcessStartInfo クラス](https://msdn.microsoft.com/ja-jp/library/system.diagnostics.processstartinfo(v=vs.110).aspx)

## shutdown

### code 

```MainWindow.xaml
<Window x:Class="_171110_t1305_shutdown.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:_171110_t1305_shutdown"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Button Content="Shutdown" Height="30" Width="100" Click="Button_Click"/>
    </Grid>
</Window>
```

```MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace _171110_t1305_shutdown
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void PowerProcess()
        {
            var psi = new System.Diagnostics.ProcessStartInfo();
            psi.FileName = "shutdown.exe";
            psi.Arguments = "/s";
            // ウィンドウ非表示
            psi.UseShellExecute = false;
            psi.CreateNoWindow = true;
            // 起動
            var proc = System.Diagnostics.Process.Start(psi);
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            // 1. 確認ダイアログ
            string cnfmsg = "";
            cnfmsg = "シャットダウン処理を続けますか?";
            MessageBoxResult res = MessageBox.Show(cnfmsg, "Confirmation", MessageBoxButton.OKCancel,
                MessageBoxImage.Question, MessageBoxResult.Cancel);
            if (res == MessageBoxResult.Cancel)
            {
                return;
            }

            // 2. shutdown or reboot
            PowerProcess();
        }
    }
}
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/0039b01f-2940-218f-3231-24e9d9a05c69.png)

### reboot

rebootするには上記のコードの一部を以下とする。

```csharp
psi.Arguments = "/r";
```

### 検索用キーワード

- シャットダウン
- 再起動
知っててよかったRubyメソッド

みなさんはじめまして。
株式会社BitStarでエンジニアインターン
をしている塩原です。

# Array

### each_with_index
配列のkeyとvalueを両方繰り返す。

```
> ["りんご", "みかん", "ぶどう"].each_with_index do |value, index|
>   puts "#{index}: #{value}"
> end
0: りんご
1: みかん
2: ぶどう
```

### all?
配列のすべての要素が真であればtrueを返す

```
> [true, true, true].all?
=> true
> [true, true, false].all?
=> false
```

### none?
配列の要素が全て偽であればtrueを返す。

```
> [false, false, false].none?
=> true
> [true, true, false].none?
=> false
```

### any?
配列の要素のうち一つでも真であればtrueを返す。

```
> [true, true, false].any?
=> true
> [false, false, false].any?
=> false
```

### one?
配列の要素のうち一つだけ真であればtrueを返す。

```
> [false, false, true].one?
=> true
> [false, false, false].one?
=> false
> [false, true, true].one?
=> false
```

### sample
配列のなかからランダムにひとつ返す

```
> ["りんご", "みかん", "ぶどう"].sample
=> "りんご"
> ["りんご", "みかん", "ぶどう"].sample(2)
=> ["みかん", "ぶどう"]
```

### zip
複数の配列をひとつにまとめる

```
> arr1 = [1, 2, 3]
> arr2 = [4, 5]
> arr3 = [6, 7, 8, 9]
> p arr1.zip(arr2, arr3)
=> [[1, 4, 6], [2, 5, 7], [3, nil, 8]]
```

# Hash

### has_key?
keyがふくまれていればtrueを返す

```
> { a: "x", b: "y", c: "z" }.has_key?(:b)
=> true

> { a: "x", b: "y", c: "z" }.has_key?(:z)
=> false
```

### invert
キーとバリューを入れ替える

```
> hash = { a: "x", b: "y", c: "z" }
> hash.invert
=> {x: "a", y: "b", z: "c"}
```

### merge
ハッシュを結合する

```
> hash1 = { a: "x", b: "y", c: "z" }
> hash2 = { d: 1, f: 2, g: 3 }
> hash3 = hash1.merge(hash2)
> puts hash3
=> {:a=>"x", :b=>"y", :c=>"z", :d=>1, :f=>2, :g=>3}
```

### partition
条件に一致する値と条件に一致しない値をそれぞれ別々の配列に振り分ける。

```
> [1, 2, 3].partition{ |x| x % 3 == 0 }
=> [[3], [1, 2]]
```
gitでコミットを取り消すコマンド

#revert
既存のコミットを取り消すコマンド．

特定のコミットのみを選択して取り消すので他のコミットに影響を与えない．
revert自身もコミットしてくれる点が特徴的。「既存コミットを取り消しました」というコミットを生成してくれる。

そのため、リモートにpushしたコミットに対しても有効である。

git-logで取り消したいコミットのハッシュを取得して，以下のようにコマンドを入力する．

```bash
$git revert <取り消したいコミットのハッシュ>
```


オプション無しだとviでメッセージ入力を求められるが，--no-editを加えることでメッセージ編集なしで行える．

```shell-session
$git revert --no-edit <取り消したいコミットのハッシュ>
```

#reset
指定したコミット以降のコミットをすべて取り消す．ローカル内の黒歴史コミットをすべてなかったことにできる．
revertと違い，reset自身はコミットされないため注意が必要．

中々強力なコマンドなので、複数人でリポジトリ共有している場合などは慎重に扱ったほうがいい。というか、revertのほうが無難。

#参考URL
http://d.hatena.ne.jp/amacou/20090117/1232201229
Uptime Config APIというものがいました


以前に[Stackdriver Uptime Checkの接続元IPアドレスを知る方法](https://qiita.com/tora470/items/1677d742a80d35e9ec55)を書いたことがあるんですが、今度Uptime CheckのIPが変わるらしくその中のドキュメント読んでたらこんなAPIがあることを知ったのでメモ。

https://cloud.google.com/monitoring/api/ref_v3/rest/v3/uptimeCheckIps/list

`GET https://monitoring.googleapis.com/v3/uptimeCheckIps
`

このAPIにアクセスすれば取得できるみたいです。
認証が必要なのでそこだけ注意なんだー。
じゃあね！
[Cinemachine] AutoDollyCameraでカメラクレーン



## 概要と準備

都市の中をキャラが走っていて、上空から追跡するカメラワークをつくる。

![dollycrane5-iloveimg-compressed.gif](https://qiita-image-store.s3.amazonaws.com/0/136286/754100fe-2ab9-6d07-a4c5-e1c5b611329f.gif "dollycrane5-iloveimg-compressed.gif")

[Cinemachine](https://www.assetstore.unity3d.com/jp/#!/content/79898)をインポート

[Cinemachine] -> [Create Dolly Camera with Track]
DollyTrackとVirtualCameraが生成される。



## DollyTrack

まずカメラが通る道をつくる必要があるので、`Waypoints`にパスを追加していく。

![スクリーンショット 2017-11-10 11.14.51.png](https://qiita-image-store.s3.amazonaws.com/0/136286/ce98dbe0-eede-7def-7c5f-eaee6b046910.png "スクリーンショット 2017-11-10 11.14.51.png")

道路に沿ってレールを組んでみた図。キャラを追いかけてレール上をカメラが移動する。現実ではありえないめちゃめちゃ長いカメラクレーンのイメージ。
![スクリーンショット 2017-11-10 11.10.17.png](https://qiita-image-store.s3.amazonaws.com/0/136286/6d2eb2c4-9f3a-9f42-2567-52a682beea3b.png "スクリーンショット 2017-11-10 11.10.17.png")



## VirtualCamera

作成したDollyTrackを使用して、自動でターゲットを追跡する設定をおこなう。

![スクリーンショット 2017-11-10 11.51.48.png](https://qiita-image-store.s3.amazonaws.com/0/136286/e5710398-42e2-0111-2f71-80cf3f7c9451.png "スクリーンショット 2017-11-10 11.51.48.png")

`LookAt`: 視線を向けるターゲットの選択
`Follow`: 追跡するターゲットの選択

`Body > Tracked Dolly`: DollyTrackを利用することを宣言し、
`Body > Path`: 使用するDollyTrackを選択する
`Auto Dolly > Enabled`: 自動でターゲットを追跡する


## おまけ

キャラを動かしているコード

```c:QueryController.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class QueryController : MonoBehaviour {

	public float rotationSpeed = 100.0f;
	public float speed = 2f;

	void Update () {
		float v = Input.GetAxis ("Vertical");
		float h = Input.GetAxis ("Horizontal");

		transform.position += transform.forward * v * speed * Time.deltaTime;
		transform.Rotate (0, rotationSpeed * h * Time.deltaTime, 0);
	}
}
```


> 参考
[Unity Cinemachine – Unity 2017 – Auto Dolly Camera](https://unity3d.college/2017/07/20/unity-cinemachine-unity-2017-auto-dolly-camera/)
[Unity2017のCinemachineをやってみた](http://blog.applibot.co.jp/blog/2017/07/31/unity2017-cinemachine/)
[[YouTube] Unity 2017.1 New Features CineMachine and Dolly Tracks](https://www.youtube.com/watch?v=AYweYkkZZK8)
【JavaScript】桁指定して四捨五入・切り上げ・切り捨て

よく忘れるので備忘録として。

# 桁指定しない場合
- 四捨五入
    - Math.round(<数値>)  
    ex1) Math.round(123.456)    // 出力：123  
    ex2) Math.round(123.567)    // 出力：124
- 切り上げ
    - Math.ceil(<数値>)  
    ex1) Math.ceil(123.456)    // 出力：124  
    ex2) Math.ceil(123.567)    // 出力：124
- 切り捨て
    - Math.floor(<数値>)  
    ex1) Math.floor(123.456)    // 出力：123  
    ex2) Math.floor(123.567)    // 出力：123

# 桁指定
四捨五入・切り上げ・切り捨ての関数は上記の通り、小数点の位置を基準とするので、数値を調整して行う。

- 小数第一位を基準とした方法  
   Math.round(123.456 * 10) / 10    // 出力：123.5
- 十の位を基準とした方法  
    Math.round(123.456 / 10) * 10    // 出力：120

# 関数にしてみる
```js
/**
 * 任意の桁で四捨五入する関数
 * @param {number} value 四捨五入する数値
 * @param {number} base どの桁で四捨五入するか（10→10の位、0.1→小数第１位）
 * @return {number} 四捨五入した値
 */
function orgRound(value, base) {
    return Math.round(value * base) / base;
}

/**
 * 任意の桁で切り上げする関数
 * @param {number} value 切り上げする数値
 * @param {number} base どの桁で切り上げするか（10→10の位、0.1→小数第１位）
 * @return {number} 切り上げした値
 */
function orgCeil(value, base) {
    return Math.ceil(value * base) / base;
}

/**
 * 任意の桁で切り捨てする関数
 * @param {number} value 切り捨てする数値
 * @param {number} base どの桁で切り捨てするか（10→10の位、0.1→小数第１位）
 * @return {number} 切り捨てした値
 */
function orgFloor(value, base) {
    return Math.floor(value * base) / base;
}
```

以上。
PayPal 定期支払いの実装方法

定期支払いとは、予め定めた金額を予め定めた周期/期間で定期的に決済する機能です。
毎回の決済時には買い手は決済操作をする必要がありません。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/210396/5d6e52d2-e23c-3873-aac7-e53f42ec1a5f.png)

## Subscription APIの実装

https://developer.paypal.com/docs/business/subscriptions/

## Webhookの登録
**※定期支払いの場合、決済はPayPalがバッチ処理で行うので運用にはなんらかの通知が必要となります。**

詳細は[こちら](https://developer.paypal.com/docs/integration/direct/webhooks/)を参照してください。

*以上で実装は完了です。後はPlan通りに課金がされ、決済時に通知（Webhook）が届くのを待ちます。*

# 定期支払いの決済結果の確認方法
以下の通知によって確認が可能です。

- 通知メール（全ての導入方法共通）
- [Webhook](https://developer.paypal.com/docs/integration/direct/webhooks/)（REST APIでの実装でかつ登録した場合のみ）

# 詳細情報
詳細は以下を参照してください。
https://developer.paypal.com/docs/business/subscriptions/

# 関連ページ
- [PayPal テスト環境 Sandboxの使い方](https://qiita.com/PPJP/items/6ba65ed21da7fba65586)
PayPal ペイアウト（送金）の導入方法

[ペイアウト](https://developer.paypal.com/docs/payouts/)とはファイルアップロードやAPIを使って複数アカウントへの一括送金を行うサービスです。

日本語概要は[こちら](https://www.paypal.com/jp/webapps/mpp/developer/pay-out)。

**※ご利用には審査が必要となります。詳しくは[お問い合わせ](https://www.paypal.com/jp/webapps/mpp/corporate/contact)にご連絡ください。**
![image.png](https://qiita-image-store.s3.amazonaws.com/0/210396/b9638060-88cc-3136-40b1-f60054cdbdcb.png)

利用方法には以下の三つの方法があります。

# 1. 管理画面からのファイルアップロード（小規模用）
PayPalにログインし、[ツール] > [全てのツール] > [一括支払い]（審査が通って有効になったアカウントだけに表示されます）からファイルをアップロードします。

詳細は[こちら](https://developer.paypal.com/docs/payouts/integrate/ui-integration/)を参照してください。

# 2. REST APIを使った実装（中規模用）
## REST APIの準備
[REST APIの呼び出し方法（各API共通部分）](https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7#rest-api%E3%81%AE%E5%91%BC%E3%81%B3%E5%87%BA%E3%81%97%E6%96%B9%E6%B3%95%E5%90%84api%E5%85%B1%E9%80%9A%E9%83%A8%E5%88%86)を参照してください。

## Payout APIの実装
[こちら](https://developer.paypal.com/docs/payouts/integrate/api-integration/)を参照してください。

## Webhookの登録
**※送金の結果はWebhookを登録することで通知されます。**

詳細は[こちら](https://developer.paypal.com/docs/integration/direct/webhooks/)を参照してください。

# 3. SFTPを使ったファイル連携（大規模用）
[こちら](https://developer.paypal.com/docs/payouts/integrate/large-batch-payouts/#how-it-works)を参照してください。

# テスト
Sandboxでテストを行う場合、送金元のアカウントは残高ありのVerifiedになったものを使ってください。
https://qiita.com/PPJP/items/6ba65ed21da7fba65586#sandbox%E4%B8%8A%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88%E7%94%A8%E3%82%A2%E3%82%AB%E3%82%A6%E3%83%B3%E3%83%88buyerseller%E3%81%AE%E4%BD%9C%E6%88%90

エラーテストなどの詳細は以下を参照してください。
https://developer.paypal.com/docs/payouts/integrate/test-payouts/

# 詳細情報
詳細は以下を参照してください。
https://developer.paypal.com/docs/payouts/

# 関連ページ
- [PayPal テスト環境 Sandboxの使い方](https://qiita.com/PPJP/items/6ba65ed21da7fba65586)
PayPal マーケットプレイス用決済の導入方法

PayPal Commerce Platformは、マーケットプレイスをはじめとするコマースプラットフォームに、強力で柔軟な決済機能を提供するフルスタックソリューションです。

# PayPal Commerce Platform for Marketplaces and Platforms
パートナー向けの最新実装方法で、マーケットプレイスやクラウドファンディング、その他のECプラットフォームを構築する様々な機能を提供します。

- [詳細情報](https://developer.paypal.com/docs/platforms/)

- [デモサイト](https://demo.paypal.com/us/demo/customize/flow?)
PayPal アカウントの設定ポイント

PayPalのアカウントの設定で気をつけるべきポイントを記載します。

# アカウント設定の概要
## 登録と設定についてのガイド
https://www.paypal.com/jp/webapps/mpp/merchant/how-to-signup-business
https://developer.paypal.com/docs/classic/admin/setup-account/

## 操作方法、仕様一般のヘルプ
https://www.paypal.com/jp/selfhelp/home

例）取引履歴に関する説明
https://www.paypal.com/jp/selfhelp/search?q=%E5%8F%96%E5%BC%95%E5%B1%A5%E6%AD%B4

# 気をつけるべきポイント
## 顧客への表示情報の設定
PayPalで支払いをすると支払い者には通知メールが送信されます。また、支払い者のPayPal画面やモバイルアプリには取引履歴が表示されます。これらの情報はデフォルトの設定だと自分の想定と異なる内容が送られている可能性もあるので、チェックして支払い者へ適切な情報が送られるようにします。

![aaaaa.png](https://qiita-image-store.s3.amazonaws.com/0/61900/808e16f6-3e68-672c-44ae-d4f1460bc47d.png)

### ①売り手の名前
これはPayPalのビジネスアカウトに登録されている事業者名が表示されます。基本的に変更は不可です。

### ②売り手のメールアドレス
支払い者へのメールには、事業情報のカスタマーサポートのメールアドレスが表示されます（以前は売り手のメインメールアドレスが表示されていましたがこれは廃止されました）。カスタマーサポートのメールアドレスが未設定の場合は何も表示されません。カスタマーサポートのメールアドレスは、PayPalの**「アカウント設定」>「プロフィール設定」>「事業情報」**のメニューに進み、「更新」を押してカスタマサポートのメールアドレスを入力することで設定できます。

※支払い者の取引詳細画面にはカスタマーサポートのメールアドレス（未設定の場合メインメールアドレス）が表示されます。

※「アカウント設定」>「販売ツール」> 「カスタマーサービスのメッセージ」を設定すると、異議申し立てを支払い者から受けた場合のメッセージの設定や、その時の連絡先（メールアドレス、電話番号）の表示、非表示をコントロールできます。

### ③購入した商品の情報
[簡単決済ボタン](https://www.paypal.com/jp/webapps/mpp/developer/standard-service/paypal-button/integration)や、[API決済](https://qiita.com/PPJP/items/db5c57991c2c3fe80ac7)で商品情報を設定できます。未設定の場合空白になりますので、後でメールや履歴を見返したときに支払い者が何を買ったかわかるためにも設定することをお勧めします。

### ④クレジットカードの明細への表記
PayPalの支払いで資金元をクレジットカードにした場合、カード会社からの明細には「PAYPAL \*XXX」(XXXが売り手によって異なる）と表示されます。
XXXの部分は以下の手順で設定できるので、支払い者がわかりやすい名称を設定してください。
https://www.paypal.com/jp/webapps/mpp/support/shop-name

### 事業情報のその他の項目
**「事業情報」の「会社のURL」**（買い手の取引履歴にカスタマーサポートURLとして表示される）などもチェックすることをお勧めします。

## 売り手保護に対する設定
アカウント登録なしの決済は売り手保護制度の対象外になるので、特に海外取引をされる売り手様には、決済時にPayPalアカウント登録を必須にする設定をすることをお勧めいたします。
**「アカウント設定」>「プロフィール設定」>「販売ツール」>「ウェブサイトの設定 – 更新」>「PayPalアカウントオプションサービスをオフにする」**

## eCheck
eCheckは海外の購入者が使える銀行口座からの後払い機能です。決済時にはステータスが保留となり、後日完了または取消となります。即時売り上げのみを対象にしたい場合は、無効にすることをお勧めいたします。
https://developer.paypal.com/docs/classic/admin/setup-account/#block-payments-funded-with-echecks

## 多通貨
多通貨を扱う場合は、対応する通貨をあらかじめ登録しておくことをお勧めいたします。初期設定では、未登録の通貨で決済があった場合未受領となり、取引履歴で受領操作を行う必要があります。
https://developer.paypal.com/docs/classic/admin/setup-account/#handle-multiple-currencies

# その他のアカウント確認項目
https://developer.paypal.com/docs/checkout/best-practices/#account-configuration
fortranの静的ライブラリと問題点

fortranにはライブラリを構築する機能がある。しかしどうもかなり癖のあるものだった、という話。

#静的ライブラリを作る
まずライブラリを作るにあたって、ソースコードに特別な文法は特に必要ない。moduleで作ればよい。

ライブラリをビルドするときは、通常のコンパイルと異なり、以下のmakefileのようにする。

```makefile:makefile
all:mylib.f90
   gfortran -c mylib.f90 -o mylib.o
   ar cr libmylib.a mylib.o
```

このとき生成するファイルはlib*.aという名前でなければならない。

#静的ライブラリを使う
静的ライブラリを使うには、コンパイル時に次のようにする。
```gfortran test.f90 -L$(mylibpath) -lmylib```
このときmylibpathにはライブラリのあるパスをフルパスで入れる。順番を間違えるとリンクがうまくいかずエラーが出る。

#問題点
ただし、調べてみたところどうやら<b>読まれるのは宣言部、つまりcontains以下のみであり、subroutineしかまとめることができないらしい。定数はおろか構造体やクラスもまとめることができない。</b>

たとえば以下のモジュールをライブラリ化したとする。

```fortran:mylib.f90
module mylib
   implicit none
   integer :: mynum = 100
   type myclass
      integer :: id
   end type myclass
contains 
   subroutine myroutine()
      write(6,*) "hello world!"
   end subroutine myroutine
end module mylib
```
これを適切な方法でライブラリ化して参照しても、myroutineは使えるがmynumやmyclassを参照することはできず、エラーが出る。

どうやらライブラリ機能はfortranが生まれたときから変わっていないようで、pythonpathのように自動で検索してインポートしてくれるわけでもないので、あまりメリットを感じない。

その上、ソースコードにはuse文を使うでもないうえ、サブルーチンの名前くらいでしか何のライブラリの要素を使っているのかわからない。makefileを見ればわかるのだが、保守性は落ちると言わざるを得ない。

なので、moduleのソースをどこかにまとめて置いておいてmakefileでその都度一緒にコンパイルするほうがいいと思う。
Pingdom でシナリオテストを作る

Pingdom のシナリオテストを試してみたのでメモ

pingdom にログイン後 https://my.pingdom.com/newchecks/transactions#check=new の URL にアクセス

アクセスするとモーダルが現れて、モーダル内の Check editor という項目でシナリオを記載していく
はじめこのシナリオの記述の仕方がよくわからなかったけど対象のURLを書くと pingdom がバックエンドでリアルタイムで処理をしてくれてるっぽく、実際のサイトにある情報をサポートしてくれるようで例えば email のフォームを入力するとかだと

<img width="687" alt="3134213412Transaction_Checks.png" src="https://qiita-image-store.s3.amazonaws.com/0/13148/1782df46-55a8-1b23-37e7-21053ab0b468.png">

のようにアクセスしたサイトの要素を候補として表示してくれるのでけっこう簡単に作れた

実際に Pingdom 自身にシナリオテストでログインしてダッシュボードページにリダイレクトされるかをチェックするテストは以下にような感じで書けた

<img width="675" alt="45345Transaction_Checks.png" src="https://qiita-image-store.s3.amazonaws.com/0/13148/ae3b7e4c-5c7d-c1cb-2cd6-a19fbb8a58d8.png">

```
Go to URL https://my.pingdom.com
Fill in field #frm_email with email
Fill in field Password with password
Click LOG IN
Wait for element .dashboard_index to exist
URL should be https://my.pingdom.com/dashboard
```

↑の email と password を自分の pingdom アカウントにすれば成功するはず
DataGirdViewのチェックボックスサイズを変更してみた

DataGirdViewのチェックボックスサイズを拡大したので紹介します。
（※なお、シンプルなチェックボックスを表示することしか行っていません。）

手順としては、DataGridViewCheckBoxCellクラスの派生クラスを作成して、下記メソッドをオーバーライドします。
protected override void Paint()：セルの描画
protected override Rectangle GetContentBounds()：コンテンツ領域を取得する

当初はPaint()だけオーバライドしていたのですが、マウスで拡大した領域をクリックしてもチェックボックスが変化しなかったため、GetContentBounds()も対応しました。

以下、コードです。

```csharp
public class DataGridViewCheckBoxCellEx : DataGridViewCheckBoxCell
{
    // チェックボックス拡大サイズ
    private const int CHECKBOX_INFLATE_SIZE = 8;

    protected override void Paint(Graphics graphics, ...)
    {
        // 塗りつぶしと枠線描画
        bool cellSelected = (elementState & DataGridViewElementStates.Selected) != 0;
        SolidBrush br = new SolidBrush(cellSelected ? cellStyle.SelectionBackColor : cellStyle.BackColor);
        graphics.FillRectangle(br, cellBounds);
        this.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle);

        // チェックボックス描画
        Rectangle checkboxRect = this.GetCheckboxBounds(graphics, cellStyle, rowIndex);
        checkboxRect.Offset(cellBounds.Location);
        ControlPaint.DrawCheckBox(graphics, checkboxRect, his.GetButtonState(formattedValue));
}

    protected override Rectangle GetContentBounds(Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
    {
        Rectangle checkboxBounds = base.GetContentBounds(graphics, cellStyle, rowIndex);
        Rectangle cellBounds = this.DataGridView.GetCellDisplayRectangle(this.ColumnIndex, rowIndex, false);
        Size marginSize = new Size(cellBounds.Width - checkboxBounds.Width, cellBounds.Height - checkboxBounds.Height);
        if (marginSize.Width < CHECKBOX_INFLATE_SIZE * 2 || marginSize.Height < CHECKBOX_INFLATE_SIZE * 2)
        {
            return checkboxBounds;
        }
        checkboxBounds.Inflate(CHECKBOX_INFLATE_SIZE, CHECKBOX_INFLATE_SIZE);
        return checkboxBounds;
    }

    private ButtonState GetButtonState(object formattedValue)
    {
        ButtonState bs = ButtonState.Normal;
        if (formattedValue != null && formattedValue is CheckState)
        {
            bs = ((CheckState)formattedValue == CheckState.Unchecked) ? ButtonState.Normal : ButtonState.Checked;
        }
        else if (formattedValue != null && formattedValue is bool)
        {
            bs = ((bool)formattedValue) ? ButtonState.Checked : ButtonState.Normal;
        }
        return bs;
    }
}
```
code > spherepts > モジュール構造調査

```txt:動作環境
Matlab (Octaveで代用)
```

### 関連

[Paper > A Comparison of Popular Point Configurations on S^2 > 球面上の点の取り方の比較 > mesh icosahedral equal area nodesが一番mesh ratioが低い](https://qiita.com/7of9/items/149c740d44d0e533dbd3)

### モジュールの整理

上記の関連コード。
https://github.com/gradywright/spherepts

一部をPythonもしくはNumpy移植しようと思う（作者との連絡はとれている）。

どのモジュールから移植するのがいいか、モジュールの構造を調査中。
[mindmup](https://atlas.mindmup.com/yasokada/code_spherepts_171110/index.html)

### 所感

@ 花森安治のちいさな絵と言葉集 美しいものを by 暮らしの手帖社 
> 美しいものは、いつの世でも お金やヒマとは関係がない

忙しくてもなんとかしよう。