OmniAICreator/Qiita-1.07M huggingface dataset:
Raspberry Pi > C > RPi_i2c_comm_180227: v0.4 > GPIOピンのレベル設定と、レベル読取まで

```
Raspberry Pi 2 Model B (以下RPi)
Raspbian Jessie
Python 2.7.9
```

I2C通信の実装をしようとしている。
その前段階として、SCLのクロック出力を行ってみる。

### code v0.4

[v0.4 @ GitHub](https://github.com/yasokada/RPi_i2c_comm_180227/releases/tag/v0.4)

### 処理概要

- GPIO26に対してクロックを出力する
    - 5クロック
    - およそ200usec
        - 最初: 260usec
        - 以降: 160usec
- GPIO05の値を読取る
    - `gpio readall`コマンドでHレベルを確認

### ファイル構成

- RPi_i2c_comm_180227.c
    - メインプログラム
- wait_msec_nsec_180301.cと.h
    - 待ち処理のための関数

### RPi_i2c_comm_180227.cのmain()

```RPi_i2c_comm_180227.c
...
int main(){
    int loop;
    int pinlvl; // pin level

    // 1. output clock at [GPIO_SCL]
    gpio_setExport(GPIO_SCL, /* bfOn=*/true);
    gpio_setDirection(GPIO_SCL, /* bfOut=*/true);        
    for(loop=0; loop<5; loop++) {
        gpio_setLevel(GPIO_SCL, GPIO_HIGH);
        Wait_about200usec();
        gpio_setLevel(GPIO_SCL, GPIO_LOW);
        Wait_about200usec();
    }
    gpio_setExport(GPIO_SDA, /* bfOn=*/false);

    // 2. read at [GPIO05]
    gpio_setExport(5, /* bfOn=*/true);
    pinlvl = gpio_getLevel(5);
    printf("SDA:%d\n", pinlvl);
    gpio_setExport(5, /* bfOn=*/false);

    return 0;
}
```

```bash
$ gcc RPi_i2c_comm_180227.c wait_msec_nsec_180301.c
$ ./a.out 
SDA:1
```

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/408d83da-2792-0710-4c9b-62cc7fffe104.png)

### 関連

- [[Resolved] Raspberry Pi > GPIO > GPIO26の出力設定(Hレベル)でssh接続が切れる > link: Why are some GPIO pins not available? | Revisionにより使えるポートはさらに変わる](https://qiita.com/7of9/items/1ac840e4544b9e18d3b7)
- [Raspberry Pi > GPIO > C > i2c_send_command_180227.c > v0.1, v0.2 > GPIO24をHレベルで出力する](https://qiita.com/7of9/items/c6d7e48f21afae6b5d1f)
- [Raspberry Pi > C > ミリ秒待つ処理 > test_delay_180301.c | wait_msec_nsec_180301.cと.h > 3.8kHz (260usec)](https://qiita.com/7of9/items/483708d5ebc38d318ce3)
Azure NSGフローログをLog Analyticsに保管する

#はじめに

本記事はAzureのNetwork Watcherで取得したNSGフローログをLog Analyticsに送り、ログの管理を容易にする方法になります。

Netowrok Watcher及びNSGフローログに関しては以下の記事をご覧ください。
[Azure Network Watcherの超概要](http://qiita.com/j-tsurumi/items/7c8ed0314df53dcd2611)

この記事を書くに至った経緯は
__NSGのDenyログやNSGの評価した通信のソースIP__などがNetwork Watcherの__NSGフローログ機能__で見れるように！！
　　↓
__JSON形式でBLOBに出力されたり__、データが1時間ごとに区切られていて何とも見づらい。。。
　　↓
Log Analyticsに取得したログを送れば統合管理もできて見やすいんじゃね！

という感じになります。

#ざっくりとした方法
既に同様なことを試した方が、世界にはいらっしゃり、Microsoftも取り上げていた模様です。
https://blogs.msdn.microsoft.com/cloud_solution_architect/2017/04/03/uploading-azure-nsg-flow-logs-to-oms/

上記の記事を読むと
①BLOBからログを取り出す
②Log Analyticsに保存できるようにJsonを整形する
③データコレクターAPIを用いてLog Analyticsに送信する
④一度送ったログのメタデータ・エントリを追加する
といった手順になります。

データコレクターAPIはREST APIクライアントからLog Analyticsにデータを送信するためのものになります。
詳細は以下の記事を参照。
[HTTP データ コレクター API を使用した Log Analytics へのデータの送信](https://docs.microsoft.com/ja-jp/azure/log-analytics/log-analytics-data-collector-api)

そしてすでに上記の手順をスクリプトにしてを公開している天才がいましたので、今回は引用したいと思います。
以下がそのスクリプトになります。
https://github.com/jboeshart/azure-nsg-flow-oms-upload/blob/master/azure-nsg-flow-oms-upload.ps1

#実行する

先ほどのスクリプトの引数にOMSワークスペースID、OMSキー、OMSログタイプ、ログの保存されているストレージアカウントキー、ストレージアカウントキー、コンテナ名を付けて実行します。
ただ、今回は__Azure Automationで1時間に1回定期的に実行__させたかったので、上記の内容はスクリプト内に書き込んでおります。

Azure AutomationでPowerShell Runbookを作成し、【編集】からスクリプトを張り付けてテスト実行！
![image.png](https://qiita-image-store.s3.amazonaws.com/0/181154/1abfa6a6-a9e0-bdaf-0633-5b3286235686.png)

実行すると以下の図のように送信した内容が列記されていきます。あまりにもログの量が多すぎるとAzure AutomationはCPUがかなり小さいので、ローカルで実行するよりも一つの処理に時間がかかることもあり、1ジョブ3時間という制限に引っかかりすべてを送信することが出来ませんのでご注意ください。


![image.png](https://qiita-image-store.s3.amazonaws.com/0/181154/2cf609a1-94f8-41f1-86ca-e54c951dd01a.png)


で、実際に送られたログをLog Analyticsで確認すると以下の様になってます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/181154/be98d72d-621e-819c-d7e3-fb53fc067a13.png)

おお！JSONファイルに比べて遥かに見やすい！
ログはNsgFlowLogs_CLというタイプで格納されるので、それを検索すれば一覧で見れます。
さらにパイプでつないで条件づければ拒否したログだけを簡単に表示できそうですね。
実際どのIPからの通信が拒否されたかを見たいのであればリストではなくテーブルの方が見やすそうなので、
テーブル形式でDenyログを表示してみました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/181154/7721b545-043f-af10-5bc9-5618dcc9a717.png)

うん。これは捗りそうです。これからのAzureでのネットワークセキュリティを高めていくのには必須になりそうな気もします。

#終わりに

調べながらLog AnalyticsのデータコレクターAPI使えば、割とどんなログでも集約できそうだなと感じております。
やはり今後はLog AnalyticsにAzureのログを集約し、MonitorやSecurity Centerなどでさらに周りを固めていくといった形が汎用的になっていきそうですね！

あと、前々から書き溜めていたこの記事はNetwork WatcherがGAしたタイミングで出そうと思っていたのに、記憶から飛んでいて少し遅いタイミングでの更新になってしまいました。
ただまだまだ現役の情報だと思いますので皆さんもぜひ使ってみてはいかがでしょうか。
ではでは！

#参考ページ
https://blogs.msdn.microsoft.com/cloud_solution_architect/2017/04/03/uploading-azure-nsg-flow-logs-to-oms/
https://docs.microsoft.com/ja-jp/azure/log-analytics/log-analytics-data-collector-api
https://github.com/jboeshart/azure-nsg-flow-oms-upload/blob/master/azure-nsg-flow-oms-upload.ps1
クリックポスト追跡番号一括読み込み（準備編）

# 動機
Amazonのセラーセントラルに、クリックポストの追跡番号を１つ１つ入力する仕事に嫌気が差し、精神崩壊する前に自動化を図った。

# 概要
本内容は以下の2部構成です。

①クリックポストのページで追跡番号リストを半自動ダウンロード
②Amazonのセラーセントラルで追跡番号リストを読み込み、自動入力

当ページでは、①のダウンロードスクリプトを記載します。

②をご覧になる方は、[クリックポスト追跡番号一括読み込み（実行編）](https://qiita.com/yuki_tanaka_lib/items/ede22a61b0ab859bdef7) からどうぞ。

# 使い方

1.[Tampermonkey](https://chrome.google.com/webstore/detail/tampermonkey/dhdgffkkebhmkfjojejmpbldmpobfkfo?hl=ja)をインストール

2.クリックポストのトップページに「番号取得」のボタンが追加されるので、クリック

![31.jpg](https://qiita-image-store.s3.amazonaws.com/0/227525/2419f32e-8ff6-14fc-4755-0873bb52f48c.jpeg)

3.表示しているページの「お問い合わせ番号」と「お届け先氏名」がセットになったテキストデータのダウンロードが開始される
※ファイル名は「clickpost*.txt」。（*)はページ番号。

4.同時に、クリックポストの次ページへ自動で移動する

5.必要なページ数の分だけ、手順2～4を、繰り返す（手順3、4は自動）

（注意）手動でページ移動をした場合、「番号取得」ボタンが消えます。その場合、ページのリロードをお願いします。また、ソートした場合は、動作いたしません。

# スクリプト

```javascript
// ==UserScript==
// @name         Click Post Tracking Number
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://clickpost.jp/mypage/index*
// @grant        none
// @require      http://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// ==/UserScript==


function getTrackingNumber(){

    var TrackingNumber = [];
    var Name = [];

    // お問い合わせ番号を取得
    $('.col_package_number > a').each(function(){
        TrackingNumber.push($(this).text());
    });
    TrackingNumber.shift();

    // 名前を取得
    $('.col_receiver > a').each(function(){
        Name.push($(this).text());
    });
    Name.shift();

    // 現在のページ数を取得
    var FileName = $('.page.current').text();
    FileName = FileName.replace(/\n/g, '');

    if(TrackingNumber.length != Name.length){
        alert('番号と名前の数が不正です。');
    }

    // 出力データ作成
    var out_data = '';
    for(var i = 0; i < TrackingNumber.length; i++){
        out_data += TrackingNumber[i] + ',' + Name[i] + '\r\n';
    }

    // データダウンロード
    $('<a>', {
        href: 'data:text/plain,' + encodeURIComponent(out_data),
        download: 'clickpost' + FileName + '.txt'
    })[0].click();

    // 次ページへ移動
    window.location.href = $('a[rel="next"]').attr('href');
}


(function() {
    'use strict';
    // ボタンを設置
    var div_element = $('<div></div>');
    div_element.addClass('nav_item');
    div_element.html('<input aria-disabled="false" class="button navi_button ui-button ui-widget ui-state-default ui-corner-all button-blue limited" role="button" type="button" value="番号取得">');
    div_element.insertBefore($('#nav_box > div:nth-child(5)'));
    div_element.on('click', function(){
        getTrackingNumber();
    });

})();
```
pwntoolsのROP関連の機能がうまく使えない時(ImportError: ERROR: fail to load the dynamic library.)

## 問題
pwntoolsのROP関連の機能を使おうとしたら、以下のようなエラーが出た。

```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python2.7/dist-packages/pwnlib/rop/rop.py", line 441, in __init__
    import ropgadget
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/__init__.py", line 14, in <module>
    import ropgadget.binary
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/binary.py", line 13, in <module>
    from ropgadget.loaders.elf       import *
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/loaders/__init__.py", line 13, in <module>
    import ropgadget.loaders.elf
  File "/usr/local/lib/python2.7/dist-packages/ropgadget/loaders/elf.py", line 13, in <module>
    from capstone   import *
  File "/usr/local/lib/python2.7/dist-packages/capstone/__init__.py", line 230, in <module>
    raise ImportError("ERROR: fail to load the dynamic library.")
ImportError: ERROR: fail to load the dynamic library.
```

## 解決法
python-capstoneを入れたら直った

```sh
$ sudo apt-get install python-capstone
```

## 参考
* ['# System/Tools' 카테고리의 글 목록 :: NoneType](http://midascopp.tistory.com/category/%23%20System/Tools)
ラズパイ(Linux) からUSB温度計で温度を測る

部屋が寒い :scream: のでいろいろ調べた。
うちではラズパイ:strawberry: が常時動いているので、これで温度が測れれば良い。
1-wire で動く[DS18B20](https://www.amazon.co.jp/KKHMF-2PCS-DS18B20-%E3%83%87%E3%82%B8%E3%82%BF%E3%83%AB%E6%B8%A9%E5%BA%A6%E3%82%BB%E3%83%B3%E3%82%B5-%E3%82%B3%E3%83%B3%E3%83%88%E3%83%AD%E3%83%BC/dp/B0757JT9GX/ref=as_sl_pc_tf_til?tag=nekyo-22&linkCode=w00&linkId=d959943c78f6b42121b8b3891db24d16&creativeASIN=B0757JT9GX) などの温度センサーを使って電子工作する方法もあるが（前にやった）、はんだ付けとか 1-wire 設定とか結構面倒くさい。
![](https://media.digikey.com/photos/Maxim%20Photos/406-TO-92_sml.jpg)

今回はもっとお手軽に USB温度計 [thermometer-528018](https://www.amazon.co.jp/OEM-USB%E6%B8%A9%E5%BA%A6%E8%A8%88-USB-thermometer-528018/dp/B004FI1570/ref=as_sl_pc_tf_til?tag=nekyo-22&linkCode=w00&linkId=67b58424c471519d134bac357647f638&creativeASIN=B004FI1570) を使ってみる。980円ぐらい。
![](https://images-na.ssl-images-amazon.com/images/I/51pXunlbKPL._SX355_.jpg)

USBで挿してlinuxから温度を取得できる。
Windowsでも専用アプリで温度は取れるけれど使い勝手は悪い。
[Windowsは、ここからTEMPer用をダウンロード 現時点ではv26が最新](http://software.pcsensor.com/pc_en.html)

USBなので、Raspberry Pi の様に I/O ポートがないLinuxマシンでも温度が測れるので、サーバー室なんかに置いても良いかも。

gitからソースをクローンする。
libusb-dev がないとエラーになる。gcc は既に入っていればインストールの必要なし。
chmod u+s temper で権限を付与しないと root でしか使えなくなるので権限を追加しておく。
実行すると、日時と温度を表示する。

```shell
$ sudo git clone git://github.com/bitplane/temper.git
  Cloning into 'temper'...
   :
$ cd temper/
$ sudo apt-get install gcc libusb-dev
$ sudo make
   :
$ sudo chmod u+s temper
$ ./temper 
28-Feb-2018 10:46,14.387618 
```
#TIPS.1 ローカルタイムにする
そのままだと日付がグリニッジ標準なので、タイムゾーンに合わせる

```temper.c
- utc = gmtime(&t);
+ utc = localtime(&t);
```
#TIPS.2 ラズパイの罠
ラズベリーパイのUSBポートに直挿しした場合、本体の温度が回り込んで5℃ぐらい温度が高くなる。
100均のUSB方向転換器なんかを間にかませると大丈夫。

後は cron から呼び出して温度を見て IFTTT に投げるなり、シェルスクリプトでなんやかやするなり応用は無限大 ∞ 。

#その他参考になりそうなサイト
[Ambient](https://ambidata.io/)
IOTデータの可視化サービス。ライブラリを入れてちょっと修正の必要はあるけれど、グラフ化することができます。
[Google Homeにセンサーの値を言ってもらう](https://ambidata.io/blog/2017/12/16/googlehome/)
言ってもらうと嬉しいよね。
[Raspberry Pi Zero用 赤外線 + 環境センサ 拡張ボード「RPZ-IR-Sensor」(端子未実装)](https://www.switch-science.com/catalog/3321/)
USBでなくてもこんなのもあります。ボード直付けなので、ボードの温度に影響されそうなのでキャリブレーションは必須かな？

#単純にラズパイだけでCPU温度を測るには

```Shell
cat /sys/class/thermal/thermal_zone0/temp
```
の値を 1/1000 すればいい。結構熱いのでビックリするかも:grimacing:
ESP32 NTPを使って時刻をGET

# ESP32のWifiを使ってネットワークから時刻を取得します。
Qiita初投稿です。　どんな感じに掲示されるのか確認。　
Aruduino SAMPLEにあるSimpleTimeをちょこっと手直しして日本時間対応にしただけのもの。　WifiのIDとパスワードを入れてコンパイル、ESP32へ転送して実行。
DHCPからIPアドレスが払い出されたら、時刻表示します。

```SimpleTime.ino
#include <WiFi.h>
#include "time.h"

const char* ssid       = "***************";  
const char* password   = "*********";

const char* ntpServer =  "ntp.jst.mfeed.ad.jp";　　//日本のNTPサーバー選択
const long  gmtOffset_sec = 9 * 3600;  //9時間の時差を入れる
const int   daylightOffset_sec = 0;　　//夏時間はないのでゼロ

void printLocalTime()
{
  struct tm timeinfo;
  if (!getLocalTime(&timeinfo)) {
    Serial.println("Failed to obtain time");
    return;
  }
  Serial.println(&timeinfo, "%Y %m %d %a %H:%M:%S");　　//日本人にわかりやすい表記へ変更
}

void setup()
{
  Serial.begin(115200);

  //connect to WiFi
  Serial.printf("Connecting to %s ", ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println(" CONNECTED");

  //init and get the time
  configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
  printLocalTime();

  //disconnect WiFi as it's no longer needed
  WiFi.disconnect(true);
  WiFi.mode(WIFI_OFF);
}

void loop()
{
  delay(1000);
  printLocalTime();
}
```
これで、シリアルのターミナル画面に１秒おきに時刻が表示されます。

ふむふむ、なんとなくQittaへの寄稿方法がわかってきた。
CarrierWave::Uploaderでversionsの拡張子を変更しているとversionsのファイルが出来ないケースがある

# 現象について
画像アップローダのCarrierWaveを使っていて、アップロードされた画像のjpgのサムネイルを作る時、ファイルの拡張子を変えてファイル名を設定しようと以下の様なコードを用意していた。

```ruby:app/uploaders/image_uploader.rb
class ImageUploader < CarrierWave::Uploader::Base
  include CarrierWave::RMagick
  version :thumb do 
    process :convert => "jpg"     
    def full_filename(for_file)
      return unless for_file.present?
      filename = super(for_file)
      filename.chomp(File.extname(filename)) + '.jpg'
    end 
  end
  （他は略）
end
```

```ruby:app/models/user.rb
class User < ApplicationRecord
  mount_uploader :image, ImageUploader
end
```

このUserのimageに image.pngを登録した後、拡張子以外は同じimage.jpgを登録して更新すると、thumb_image.jpgが消えてしまう現象が起きた。
（※ image.pngを登録している段階では、thumb_image.jpgは存在する）

# 原因
CarrierWaveでは、ファイルを登録後、versionsを作成して古いversionsを削除しているが、この時、古いversionsとファイル名が一緒なため
ファイルを削除する際、新しく作ったversionの画像も削除してしまっている。
元のファイル名が一致した時は削除しないように回避されているが、別のファイル名だがversionsで一致すると言うケースでは回避策が取られていない。（元のソースコードだと発生しないので当然だけど）

# 対策1: 以前のバージョンのファイルを削除しないようにする
[CarrierWaveで画像更新時に以前のバージョンを削除しない](https://qiita.com/fukayatsu/items/876e2bc9d112f63a6213)を参考に、以前のバージョンを削除しないようにすれば解決はする。
古いファイルが残ってしまうので、使えないケースもありそう

# 対策2: 生成タイミングを削除タイミングの後にする
バッドノウハウ感のある対策だけど、以下の様に、mount_uploaderでafter_save に作成と削除のコールバックが登録されているので、作成のコールバックを登録し直すことで、削除後に作成する様になる

```ruby:app/models/user.rb
class User < ApplicationRecord
  mount_uploader :image, ImageUploader
  skip_callback :save, :after, :store_image!
  save_after :store_image!
end
```

注意: :store_iamge!の imageの部分はカラム名なので、適宜書き換えてください

# 取り敢えず

対策2を採用したんだけど、もっと良い方法があれば是非指摘ください
統計学入門(東京大学出版会)第一章　要約

意気込み：6/17日の統計検定にむけてがんばるぞい！
　　　　　2級と準1級を目標にしています。

##統計学が発達した背景
統計学が発達した要因は人間及び社会の活動から起こり、その活動で得られた知識が融合して大きな理論体系が出来上がった。
具体的に言うと

①ゲームのテーブルから起こった確率論
②常備軍や国家財政上の必要から起こった国家状態の統計
③古代地中海貿易での、海上保険の計算
④ペストをきっかけとする死亡率表の研究
などである。
[Advanced Theory of Statistics](https://www.amazon.co.jp/Advanced-Theory-Statistics-M-Kendall/dp/0028476409) という本に統計学が発達した要因が詳しく書かれているのでいつか読んでみようと思う。
ここで重要なことは**現象の法則性**に対する人間の関心が統計学を生み出したということです。
例えば③海上保険において「難波事故は何月に発生しやすいか？」や④ペストにおいて「どのような人間あるいはどの国が死亡する確率が高いか」といういずれも**傾向や法則を知りたいニーズがあって統計学が発達した**ことが言えます。
##記述統計学と推測統計学
**現象の法則性**を知るために、**すべて**を(例えば日本国全員の高校生の得点)調査してそこから日本人高校生の得点の傾向・法則を発見する→**記述統計学**
**現象の法則性**を知るために、**一部**を(例えば新宿区全員の高校生の得点)調査してそこから日本人高校生の得点傾向・法則を発見する→**推測統計学**

**記述統計学**で代表的なものは**[国勢調査](http://www.stat.go.jp/data/kokusei/2010/gaiyou.htm#tyousazikou_6)**であり、**全数調査**の原理にそって行われています。
そして歴史的にみて、統計は国家の状況を歴史的に記述するものであったのです。詳しくは[こちら](http://www.stat.go.jp/teacher/c2epi1.htm)を参考に。

##近代統計学の確率
ケトレー(1796-1874)は全ての人間集団には「平均」という型があり、個人差はあっても最もよく観察されるのは「平均」であるといった。先の国勢調査のような**大量観察**は一定の普遍性をもった**法則**をもたらす。

メモ：
ピアソンによって近代統計学理論の基礎が定まった。積率相関係数を導入したので、飛躍的に統計学が発展した→標本と母集団が区別されるようになった。
フィッシャーによって推測統計学の論理が築かれた。仮説検定及び推定、分散分析、実験計画法。

##質的データと量的データ
説明は割愛します。Pythonで質的データと量的データの要約統計量を出したいなら、

```python

#dfはデータフレーム
df.describe()               #量的データのみの要約統計量
df.describe(include=['O'])  #質的データのみの要約統計量
df.describe(include=['all'])#すべての要約統計量

```

と記述すれば大丈夫です。

##時系列データとクロス・セクション・データ
同一の対象の異なった時点での観測値データを**時系列データ**
異なった対象の同じ時点での観測値データを**クロスセクション・データ**
時系列データとクロスセクション・データを合わせたものを**パネルデータ**
と呼ぶ！

###実験及び調査プロセス
①仮説と分析する対象を決める。また全数調査か標本調査か定義する。
②実験あるいは調査によって**原データ**を獲得する。
 因みにデータ獲得の作業を自然科学では**実験**と呼び人文・社会科学分野では**調査**と呼ぶ
###統計資料
実験・調査は費用と時間がかかるので、国や研究機関といった第三者が行った調査結果を統計データとして利用することが多く行われる。その統計データは**統計資料**と呼ばれる。
統計資料は第一義統計と第二義統計の2種類に分類される。
**第一義統計**とはあらかじめ統計資料を作成する目的で調査を行いその結果を集計したものである。
(社会分野が主なので調査と表現している)
代表的な資料は国勢調査報告や事業所統計調査報告である。
**第二義統計**(または業務統計)は統計資料の作成が目的でない資料を集計して得た統計資料である。
代表的な資料は貿易統計・犯罪統計である。
また、統計資料を加工して作られた統計資料を**二次統計**と呼ぶ。
代表的なものは物価指数・国民経済計算。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/224195/a6867fa2-2749-33a9-7da7-6e57fae7bcf6.png)
【学習メモ】daemontoolsでreadproctitle service errorsを誤ってkillしたら

## はじめに
```readproctitle service errors: ...```が出て、そのプロセスをkillしたら、defunctが発生して何度もrunのexecを実行する状態になりました。

ここでは発生する原因は**追及しません**.

```
initctl restart svscan
```

で直りました。
当然といえば当然ですが。

```/command/svscanboot/```の子プロセス```\_svscan /service```と並んで、```readproctitle service errors: ...```が出ますが、これは出たままでも動作するようです。


## 環境
```
CentOS 6.9
daemontools 0.76

実行ファイル
/tmp/test_proc/run

起動
cd /service ; ln -s /tmp/test_proc test_proc
```

## 消したあとにやったこと
test_procの子プロセスを削除すると、本来ならrunに書かれたexecが起動するはずですが、defunctになってしまいます。

```bash:表示例
\_ supervise test_proc
   \_ [run] <defunct>
```


```svc -dx test_proc```で再起動しても、一瞬起動してすぐにdefunctになります。その後起動とdefunctを繰り返します。

```text:test_procの起動時間
# svstat test_proc
test_proc: up (pid 15324) 1 seconds
# svstat test_proc
test_proc: up (pid 15333) 1 seconds
# svstat test_proc
test_proc: up (pid 15338) 1 seconds
# svstat test_proc
test_proc: up (pid 15344) 1 seconds
```

こうなると、```/tmp/test_proc/supervise```を削除したり、```/service/test_proc```をアンリンクしたりしてもdefunctが発生してしまいました。

ただし、```/tmp/test_proce/run &```は正常に起動します。

結局```initctl restart svscan```で元通りになりました。

参考資料
[daemontools HOW-TO (α版)(www.emaillab.org)](http://www.emaillab.org/djb/daemontools/daemontools-howto.html)
[daemontools のページ(www.unixuser.org/~euske/)](http://www.unixuser.org/~euske/doc/daemontools/index.html)
[daemontools で defunct な multilog が生まれる現象を再現しようと試みたメモ(blog.livedoor.jp/sonots/)](http://blog.livedoor.jp/sonots/archives/39495891.html)
rubyのおけるDateTime#===の挙動について

```ruby
require 'date'

DateTime.new(2018, 3, 1, 12, 30, 15) == DateTime.new(2018, 3, 1, 20, 30, 15)
=> false

DateTime.new(2018, 3, 1, 12, 30, 15) === DateTime.new(2018, 3, 1, 20, 30, 15)
=> true

DateTime.new(2018, 3, 1, 12, 30, 15) === DateTime.new(2018, 3, 2, 12, 30, 15)
=> false
```

このような挙動をする原因について解説します。
まず、[DateTimeクラスのリファレンス](https://docs.ruby-lang.org/ja/latest/class/DateTime.html)をみてみましょう。
このクラスには`===`の実装はありません。
親クラスである[Dateクラス](https://docs.ruby-lang.org/ja/latest/method/Date/i/=3d=3d=3d.html)には`===`の実装があり"同じ日なら真を返します。"と書いてあります。
ということは`DateTime`の`===`は`Date`の`===`を実行しており***日時ではなく日***の比較しかしていないことがわかります。
よって日付は同じで時間だけがずれている場合は`true`を返し、日付が変わると`false`を返すという挙動になります。

ちなみに、[ここのコード](https://github.com/rspec/rspec-support/blob/master/lib/rspec/support/fuzzy_matcher.rb#L18)にぶち当たったのが原因で調べました。

# 追記

[rubyのソースコード](https://github.com/ruby/ruby/blob/trunk/ext/date/date_core.c#L6381)にも書いてありました。
Laravel5.5のコマンドの使ったやつめも

# artisan

## php artisan list
コマンドリストを見る。

```shell
$ php artisan
```
のみでも可。

## php artisan tinker
簡単なphpの検証ができる。
モデルのinsertとかも出来る。

## php artisan cache:clear
キャッシュのクリア

## php artisan make:migration
マイグレーションファイルの生成。
/database/migrations
内に新しいファイルが出来る。

## php artisan migrate
/database/migrations
内のマイグレーションファイルを実行。

## php artisan migrate:rollback [num]
実行したmigrateを巻き戻す。
最後に数字を入れると何個巻き戻すか指定できる。

## php artisan route:list
現在指定しているパスの一覧を取得する。
自動でnameが生成されているもののnameを確認したりするのに便利。
これやって気づいたけど、laravelのroutenameって
基本は.(ドット)区切りなんですね。#で区切ってました。

# npm 

## npm run dev
/resources/assets内のcss/javascriptのコンパイル
Log4j2 のdate出力パターン定義


- 細かい[フォーマット指定](https://logging.apache.org/log4j/2.0/manual/layouts.html#PatternLayout)ってどこに載ってるんでしょ？雑な性格なのか見つけられませんでしたw

## 要はこう出力したい！→ [2018-03-01T13:00:00.123+09:00]

- いろいろググってわかりました！

```xml
<PatternLayout pattern="[%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}], %-5p, %t, %c,%m%n" />
```

- 2箇所がミソでした。
	1. フォーマット文字列のなかで文字を出力したいときはシングルクォートで囲む'T'
	1. タイムゾーンのいわゆるZはXXXと定義
WordPress に不正アクセスしにくるので対処

2018/3/1


```

サイト「 ****** 」の新規ユーザー登録:

ユーザー名: aji*****co

メールアドレス: era****ye@asas.domailnew.com


```

サーバにログインして、apacheのアクセスログを調べる。

```

91.200.12.7 - - [01/Mar/2018:02:24:44 +0000] "GET /wp-login.php?action=rp HTTP/1.0" 200 4724 "http://**********/wp-login.php?action=rp" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 YaBrowser/17.10.0.2017 Yowser/2.5 Safari/537.36"
91.200.12.7 - - [01/Mar/2018:02:24:45 +0000] "POST /wp-login.php?action=resetpass HTTP/1.0" 200 1721 "http://**********/wp-login.php?action=rp" "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 YaBrowser/17.10.0.2017 Yowser/2.5 Safari/537.36"
91.200.12.7 - - [01/Mar/2018:02:59:59 +0000] "POST /wp-login.php HTTP/1.0" 302 384 "http://**********/bbp-register/" "Mozilla/5.0 (Windows NT 7.0; WOW64; rv:33.1) Gecko/20100101 Firefox/33.1"
91.200.12.7 - - [01/Mar/2018:03:00:02 +0000] "POST /wp-login.php HTTP/1.0" 200 4049 "http://**********/bbp-register/?checkemail=registered" "Mozilla/5.0 (Windows NT 7.0; WOW64; rv:33.1) Gecko/20100101 Firefox/33.1"
91.200.12.7 - - [01/Mar/2018:03:16:01 +0000] "POST /wp-login.php HTTP/1.0" 302 384 "http://**********/bbp-register/" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
91.200.12.7 - - [01/Mar/2018:03:16:03 +0000] "POST /wp-login.php HTTP/1.0" 200 4045 "http://**********/bbp-register/?checkemail=registered" "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36"
```

このアドレスのURLは？

```


nanbuwks@LATITUDE:~$ dig -x 91.200.12.7

; <<>> DiG 9.10.3-P4-Ubuntu <<>> -x 91.200.12.7
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4262
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;7.12.200.91.in-addr.arpa.	IN	PTR

;; ANSWER SECTION:
7.12.200.91.in-addr.arpa. 3600	IN	PTR	dsystemip5.vhoster.org.

;; Query time: 192 msec
;; SERVER: 127.0.0.1#53(127.0.0.1)
;; WHEN: Thu Mar 01 11:34:12 JST 2018
;; MSG SIZE  rcvd: 89
```

ということで、このアドレスをブラウザで開くと真っ赤っ赤。



![image](https://qiita-image-store.s3.amazonaws.com/0/139524/e69e12b3-c0a5-f4c1-1cee-e5d1f898307a.png)


時間があるときに、どんな攻撃コードが降ってくるか調べてみたいところです。

今回は、安直に該当アドレスをフィルタリングして様子見。
【Mac】Nordic nRF52の開発環境を構築する(SEGGER Embedded Studio)


## はじめに

Macユーザーのみなさんこんにちは。
ついにMacでもNordic nRF51とnRF52のFW開発ができるようになりました。
Segger Embedded StudioのMac版が無償で使えるようになったのです(Nordic Semiconductor製デバイス限定)


#### Segger Embedded Studio
https://www.nordicsemi.com/Software-and-Tools/Development-Tools/Segger-Embedded-Studio

>Nordic nRF51とnRF52シリーズSoCによるアプリケーションを開発するにあたり、デベロッパーはEmbedded Studioを制約なく無償で利用できることになります。

なんということでしょう。無償です。良い時代になりました。
さっそくインストールしましょう。


## 環境
以下の環境で試しました。 

- MacBook Air(Early2015)
- macOS High Sierra 10.13.3
- Nordic nRF52 DK


## ダウンロード
ここからダウンロードしてください。
https://www.segger.com/downloads/embedded-studio
![スクリーンショット 2018-02-26 22.34.18.png](https://qiita-image-store.s3.amazonaws.com/0/102273/25e5bcd7-5ce3-203d-db2d-8a7a63a86872.png)


## インストール

![スクリーンショット 2018-02-27 9.55.34.png](https://qiita-image-store.s3.amazonaws.com/0/102273/be0d8550-8063-13a0-d734-edd7b5968351.png)
インストーラをダブルクリックして


![スクリーンショット 2018-02-27 9.56.23.png](https://qiita-image-store.s3.amazonaws.com/0/102273/27a44ff5-41ab-c28c-4666-8a172b0aa433.png)
テキトーにポチポチ押していくと

![スクリーンショット 2018-02-27 9.56.43.png](https://qiita-image-store.s3.amazonaws.com/0/102273/fa4bab93-6f68-f696-15af-eea16b047817.png)
完了です！

## 起動する
![スクリーンショット 2018-02-27 10.04.19.png](https://qiita-image-store.s3.amazonaws.com/0/102273/840d4355-4418-c499-2aa5-d159c6d180a5.png)
Segger Embedded Studioを起動すると、こんな感じ

## ライセンス登録
![スクリーンショット 2018-02-27 10.05.05.png](https://qiita-image-store.s3.amazonaws.com/0/102273/ec0e31c3-8d8e-a3f1-be12-975070f1b3da.png)
ビルドアイコンをクリックしてビルドしてみると

![スクリーンショット 2018-02-27 10.05.15.png](https://qiita-image-store.s3.amazonaws.com/0/102273/965c9039-4df7-ca85-d167-36ba0da1590f.png)
ライセンス登録用の画面が出ますので、Get a Free Licenseボタンを押してライセンスを取得します。

![２.png](https://qiita-image-store.s3.amazonaws.com/0/102273/e67137f5-327b-3c0e-7a75-be41fe893c8e.png)

各項目を入力してRequest Licenseボタンを押すと、メールでアクティベーションコードが送られてきます。


![スクリーンショット 2018-03-01 0.14.16.png](https://qiita-image-store.s3.amazonaws.com/0/102273/b9248c91-8a7f-a587-08b5-a4f9e6058c20.png)
メニューから'Tools' -> 'License Manager...' -> 'Activate Embedded Studio'.でアクティベーション画面が開きます。
メールで届いたアクティベーションコードをコピペしてInstall Licenseをクリックします。

## ビルド
![スクリーンショット 2018-03-01 0.11.33.png](https://qiita-image-store.s3.amazonaws.com/0/102273/879e7dc8-bd9a-b2bf-85f4-0d5566a7fc02.png)
ビルド出来ました。これでWindowsとおさらばできますね。

## 参考
https://www.nordicsemi.com/jpn/node_206/node_305/Product-Related-News/Nordic-Semiconductor-nRF51-nRF52-SoC-Embedded-Studio-IDE
https://www.youtube.com/watch?v=YZouRE_Ol8g
https://www.youtube.com/watch?v=fRAG6yOqt_4
https://www.nordicsemi.com/eng/Products/Bluetooth-low-energy/nRF52-DK
ホストでsshポートフォワーディングした先にDockerコンテナ内から接続する

ホストでsshポートフォワーディングした先にDockerコンテナ内から接続する方法をまとめました。
この記事で利用する「ホスト」はDockerコンテナに対するホストを指します。

# 手順
## 1. ホスト側でlo0にエイリアスをはる

```:ホスト側
sudo ifconfig lo0 alias 10.200.10.10/24
```

上では、10.200.10.10としていますがプライベートipであればなんでも良いです。

## 2. ホスト側でsshポートフォワーディング

```:ホスト側
ssh -f -N -g -L 8080:localhost:80 リモートサーバ
```

今回は、リモートサーバの80番ポートをローカル(ホスト)の8080番ポートにバインディングします。
ココで重要なのは`-g`オプションです。Docker内からのホストへの接続時に、手順1で示したエイリアスへ接続します。この通信は外部からの接続とみなされてしまいます。そこで、外部からの接続に対応するために`-g`オプションが必要となります。詳しくは`man ssh`で`-g`オプションを確認してください。

## 3. Dockerコンテナ内から接続

```:Docker内
curl 10.200.10.10:8080
```

手順1で貼ったエイリアスにDocker内からアクセスするとリモートサーバの80番ポートにつながります。

# まとめ
上の方法で、ポート制限がなされたサーバなどにsshポートフォワーディング経由でDocker内から接続することができるようになります。もしもっといい方法があったら教えてください。
Tinkercad > UI > ISOメートルねじのねじ山数を増やす | Helix (ばね)

ブラウザ動作するAutoDeskのTinkercad。

「ISOメートルねじ」や「Hexli (ばね）」などのオブジェクトがある。
ねじ山数やばねの巻き数を増やすのは、オブジェクトをクリックした時に表示されるパラメータを変更すればいいようだ。

![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/64e9acae-d24f-3214-da30-a0a75eca614b.png)

- ISOメートルねじ
    - セグメント: 一巻の解像度?
    - 回転: ねじ山数を変更
        - Max 20
    - etc

回転は20が上限なので、30cmの全ネジなどは定義できないようだ。オブジェクトを足すことになるのだろうか?(あるいはShape Generatorで作成する）。

- Helix
    - 巻き数
    - 底面半径
    - 上面半径: 底面半径と合わせて、ばねの外形を決める
    - Separation: 巻きの間隔
    - Sketch Diameter: 断面の直径
Jenkinsのグローバル環境変数をジョブから変更する

# Jenkinsのグローバル環境変数をジョブから変更する

EnvInject Pluginなんかはジョブ中の環境変数しか変えてくれません。
一方いろいろな理由でグローバルな環境変数を変更したいよーということがあります。
そういう時のやりかた

# やりかた

1. 以下のコードをPipelineジョブで貼り付けます。
2. 環境変数名をKey,値をValueとしてパラメータを追加します。
3. 適当な値で実行してIn-process Script Approvalのメソッドの実行を許可しまくります。（もしくはSandboxを外します。）
4. おしまい

```groovy
import jenkins.model.*
import hudson.model.*
import hudson.slaves.*

instance = Jenkins.getInstance()

env_key = Key
env_value = Value

props = instance.getGlobalNodeProperties().getAll(hudson.slaves.EnvironmentVariablesNodeProperty.class)

if(props.empty) {
  def entry = new EnvironmentVariablesNodeProperty.Entry(env_key, env_value)
  def evnp = new EnvironmentVariablesNodeProperty(entry)
  instance.getGlobalNodeProperties().add(evnp)
} else {
  for (prop in props) {
    prop.envVars.put(env_key, env_value)
  }
}

instance.save()
```

ただ、jenkinsさん的にはセキュリティ的にちょっと触ってほしくないクラス触ってるので別の方法ないかなーとは思いました。

# 参考
https://code.i-harness.com/ja/q/209a636
[超初心者向け] Railsアプリを効率よく開発する方法

# はじめに
ここではRailsアプリ作成が完成した後も、引き続き、効率よくBootstrapを活用して、時間をかけずにサービスインできるようにするための方法を研究したいと思います。

# 設定環境
- OS
    - Mac OS X
        - 10.12.6
- Software
    - PostgreSQL
        - 10.1
    - Ruby
        - 2.5.0
    - Rails
        - 5.1.5

# Railsアプリを効率よく作成する方法
ここではRailsアプリを効率よく作成する方法を研究していきたいと思います。

やりたいこととしては以下です。
**・Railsでユーザ管理アプリ作成**
**・ユーザー管理アプリで一覧表示、詳細表示、登録、削除を可能にする**
**・データベース(postgresql)にテーブルを定義**
**・Bootstrapで見栄えをよくする**

それでは上記４つを順番に研究していきましょう。
## Railsアプリを作成
現在確認中


## ユーザ管理（ユーザの一覧表示、詳細表示、登録、削除）のアプリ作成
現在確認中



## データベース(postgresql)にテーブルを定義
現在確認中


## Bootstrapで見栄えをよくする
http://asobo.hatenablog.jp/entry/2016/01/17/120609

## 参考サイト
http://asobo.hatenablog.jp/entry/2016/01/17/120514
Markdown でコードの一部を強調したい

コード中で太文字や文字色指定ができると書く側としては直感的なのですが、できないので、他の方法を考えてみます。
ここに書いた以外にも良い方法ないかな…？

# 1. コメントを添える

` // ここに追加` や ` # ここを書き換え` みたいに書く。

- メリット
    - 簡単
- デメリット
    - コードが大きいとやっぱり分かりにくい
    - コメントがない言語だとつらい

# 2. 省略する

単純に、強調したい部分以外を省略する方法。
どこを省略したか分かるように「...」などを書く。
場所を分かりやすく説明を添える。

> `hoge.js` の `fuga()` 関数の一番後ろに `return piyo;` を追加します。
> 
> ```js:hoge.js
> // ... 略
>     
>     return piyo;
> }
> 
> // ... 略
> ```

<!-- -->

> `hoge.json` で `fuga.piyo` の値を `"hogera"` に書き換えます。
> 
> ```js:hoge.json
> ... 略
>   "fuga": {
>     "piyo": "hogera"
>   },
> ... 略
> ```

- メリット
    - 全体のコードが大きかったとしても分かりやすい
- デメリット
    - JSON のようなコメントが書けない言語だと、シンタックスハイライトが上手くいかない可能性がある
    - 編集・追加・削除を表現しにくい

# 3. diff を使う

diff のシンタックスハイライトで見やすくする。
コードが小さい場合は略さずに diff にしてしまったほうが見やすいかも。
ここでは人力で `+` `-` を付け加えている (インデントは気にしない) 。

> `hoge.js` の `fuga()` 関数の一番後ろに `return piyo;` を追加します。
> 
> ```diff:hoge.js
> // ... 略
>     
> +    return piyo;
> }
> 
> // ... 略
> ```

<!-- -->

> `hoge.json` で `fuga.piyo` の値を `"hogera"` に書き換えます。
> 
> ```diff:hoge.json
> ... 略
>   "fuga": {
> -    "piyo": null
> +    "piyo": "hogera"
>   },
> ... 略
> ```

- メリット
    - 編集・追加・削除を表現しやすい
- デメリット
    - 言語ごとのシンタックスハイライトは使えない

参考「[markdown で GitHub のような diff を表現する - Qiita](https://qiita.com/kakakakakku/items/461e000587b707785e79)」
［Python］NumPy以外のライブラリを利用せずにニューラルネットワークを実装する方法

### 共有すること
NumPy以外のライブラリを利用せずに、ニューラルネットワークを実装する方法

### 共有する理由
「ゼロから学ぶディープラーニング」第3章の内容を忘れないようにするため



### ニューラルネットワークとは？（あくまでも自分の解釈）
ヒトの脳神経（ニューロン）と同様の処理を、コードを使って実装したもの

###ニューラルネットワークを自分で実装して抱いた感想
・人工知能の処理は、基本的には`Y = AX + B`の計算を大量にPCにさせたもの
・ただ`Y = AX + B`は線形であるため複雑な処理ができなくなる
・そこで非線形関数である《活性化関数》を利用すると、複雑な処理が可能になるこ
・《ソフトマックス関数》は、処理結果の表示に利用する（【例】◯の可能性:５９％ ×の可能性:４１％）ことがわかった
・行列の積（旧課程「高校数学ⅢC」）をNumPyで実装する方法を理解すると、案外簡単
・ハッシュを使えば簡単にニューラルネットワークの重み・バイアスを事前に設定できることがわかっ

###下記のコードで書いた内容
・ニューラルネットワークの重み・バイアスを設定する方法
・ニューラルネットワークの処理を行列の積を使って実装する方法（順伝播）

###下記のコードで書いていない内容
・入力した値を訓練データ・テストデータに分割する方法
・入力した訓練データを任意の回数訓練させる方法
・学習したデータをもとに判断した結果が、実際とはどれだけ乖離があるか測定する方法
・結果の誤差をもとに重み・バイアスを自動で更新する方法（逆伝播）

### コード例
```python:neural_network.py
import numpy as np

#活性化関数（ここでは非線形関数である《シグモイド関数》を利用）
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

#出力値を表示するために利用する関数《ソフトマックス関数》
def softmax(x):
    max = np.exp(x)
    exp_x = np.exp(x - max)
    sum_exp_x = np.sum(exp_x)
    y = exp_x / sum_exp_x
    return y

#重み・バイアスを事前にセット
def init_network():
    network = {}
    
    #隠れ層①（２行３列の行列）
    network['W1'] = np.array([[0.1,0.2,0.3],[0.4,0.5,0.6]])
    network['B1'] = np.array([0.1,0.2,0.3])
    
    #隠れ層②（３行２列の行列）
    network['W2'] = np.array([[0.1,0.2],[0.3,0.4],[0.5,0.6]])
    network['B2'] = np.array([0.1,0.2])
    
    #隠れ層③（２行２列の行列）
    network['W3'] = np.array([[0.1,0.2],[0.3,0.4]])
    network['B3'] = np.array([0.1,0.2])

    return network #networkを返り値としないと、printされない。

#ニューラルネットワークの処理を実装
def forward(network,X):
    W1,W2,W3 = network['W1'],network['W2'],network['W3']
    B1,B2,B3 = network['B1'],network['B2'],network['B3']

    A1 = np.dot(X,W1) + B1
    Z1 = sigmoid(A1)
    A2 = np.dot(Z1,W2) + B2
    Z2 = sigmoid(A2)
    A3 = np.dot(Z2,W3) + B3
    Y = softmax(A3)

    return Y

network = init_network()
x = np.array([1.0,0.5])
y = forward(network,x)

print(y)
```

### 今後の課題
上記の「下記のコードで書いていない内容」をNumPy以外のライブラリを使わずに実装

### 参考資料
「ゼロから学ぶディープラーニング」　第3章
Raspberry Pi 3にdocker-composeを入れる

https://qiita.com/hisurga/items/fc26f8823c92fc727307
https://www.berthon.eu/2017/getting-docker-compose-on-raspberry-pi-arm-the-easy-way/
上の記事の丸パクリだが、master に既に存在するDockerfile.armhf を利用するという所に微小な新規性を感じたので記事にする

```
git clone https://github.com/docker/compose.git
cd compose
sudo docker build -t docker-compose:armhf -f Dockerfile.armhf .
sudo docker run --rm --entrypoint="script/build/linux-entrypoint" -v $(pwd)/dist:/code/dist -v $(pwd)/.git:/code/.git "docker-compose:armhf"
# ちなみにfish
sudo docker run --rm --entrypoint="script/build/linux-entrypoint" -v (pwd)/dist:/code/dist -v (pwd)/.git:/code/.git "docker-compose:armhf"
```

dist の下にdocker-compose が作成されるのでコピー

```
sudo cp dist/docker-compose-Linux-armv7l /usr/local/bin/docker-compose
docker-compose --version
docker-compose version 1.20.0dev, build 4ceeaad
```

わーい動いた
PhpStorm の Database で booleanはどう表示されているか


- `✔︎` true
- `空白` false
- `-` null


![Screen Shot 2018-03-01 at 12.19.30.png](https://qiita-image-store.s3.amazonaws.com/0/109241/89680866-98b2-035a-cebd-4fee0ab42d73.png "Screen Shot 2018-03-01 at 12.19.30.png")

↑ だと

- true
- null
- false
- null
- false
電子ペーパー を ESP32 と Arduino開発環境で使う

2019年11月28日追記：新しいライブラリ GxEPD2 を使った記事を書きました
→ 「電子ペーパー を ESP32 と Arduino開発環境で使う その2」
https://qiita.com/nanbuwks/items/266bf61726b005d8e221
以下は旧いライブラリで試したものです。

------------

WaveShareの電子ペーパーモジュール。
https://www.waveshare.com/wiki/2.9inch_e-Paper_Module_(B)

2.9inの白黒赤のもの。

実態は GoodDisplay社 の E-Paper Display にインターフェース基板をつけたもの。
GDEW029Z10 2.9 inch 128 x 296 3 color SPI display

GDEW029Z10 には IL0373コントローラが内蔵されている。
http://www.good-display.com/download_detail/downloadsId=535.html

これらを使うことの出来るライブラリとして、GoodDisplay SPI ディスプレイ用の Arduino ライブラリがある。
https://github.com/ZinggJM/GxEPD
このモジュールを使った。

これを試してみた。

# 環境
- ちょっと前のArduino1.6.9
- Ubuntu Linux 16.04 AMD64
- ESP32

Arduino環境からESP32にプログラムできるようになっているとします。

# インストール

まず上記ページから ZIP でダウンロードしました。

ライブラリのインストール方法は通常のライブラリと同様。
- GxEPD-master.zipを解凍して、
- できたGxEPD-masterフォルダを
- Arduinoのスケッチが保存されるフォルダのlibrariesフォルダ内部に移動

ArduinoIDEを起動して、サンプルプログラムGxEPD_SPI_TestExampleを使う。

以下の箇所をモジュールに合わせて有効なものを選びなおす。

```

// select the display class to use, only one
//#include <GxGDEP015OC1/GxGDEP015OC1.cpp>    // 1.54" b/w
//#include <GxGDEW0154Z04/GxGDEW0154Z04.cpp>  // 1.54" b/w/r
//#include <GxGDE0213B1/GxGDE0213B1.cpp>      // 2.13" b/w
//#include <GxGDEW0213Z16/GxGDEW0213Z16.cpp>  // 2.13" b/w/r
//#include <GxGDEH029A1/GxGDEH029A1.cpp>      // 2.9" b/w
#include <GxGDEW029Z10/GxGDEW029Z10.cpp>    // 2.9" b/w/r
//#include <GxGDEW027C44/GxGDEW027C44.cpp>    // 2.7" b/w/r
//#include <GxGDEW027W3/GxGDEW027W3.cpp>      // 2.7" b/w
//#include <GxGDEW042T2/GxGDEW042T2.cpp>      // 4.2" b/w
//#include <GxGDEW042Z15/GxGDEW042Z15.cpp>    // 4.2" b/w/r
//#include <GxGDEW075T8/GxGDEW075T8.cpp>      // 7.5" b/w
//#include <GxGDEW075Z09/GxGDEW075Z09.cpp>    // 7.5" b/w/r
```


実際の接続に合わせて設定を直す。ESP32で使うので、以下の箇所を
（変更前）

```
#elif defined(ESP32)

// pins_arduino.h, e.g. LOLIN32
//static const uint8_t SS    = 5;
//static const uint8_t MOSI  = 23;
//static const uint8_t MISO  = 19;
//static const uint8_t SCK   = 18;

// GxIO_SPI(SPIClass& spi, int8_t cs, int8_t dc, int8_t rst = -1, int8_t bl = -1);
GxIO_Class io(SPI, SS, 17, 16); // arbitrary selection of 17, 16
// GxGDEP015OC1(GxIO& io, uint8_t rst = D4, uint8_t busy = D2);
GxEPD_Class display(io, 16, 4); // arbitrary selection of (16), 4
```
↓
（変更後）

```
#elif defined(ESP32)

// pins_arduino.h, e.g. LOLIN32
//static const uint8_t SS    = 5;
//static const uint8_t MOSI  = 23;
//static const uint8_t MISO  = 19;
//static const uint8_t SCK   = 18;

GxIO_Class io(SPI, SS, 16, 17);
GxEPD_Class display(io, 17, 21);
```


コンパイルすると、

```

In file included from /tmp/arduino_modified_sketch_971536/GxEPD_SPI_TestExample.ino:51:0:
/home/nanbuwks/Arduino/libraries/GxEPD-master/GxEPD.h:5:17: fatal error: SPI.h: No such file or directory
compilation terminated.
```

とか

```


In file included from /tmp/arduino_modified_sketch_78349/GxEPD_SPI_MultiExample.ino:45:0:
/home/nanbuwks/Arduino/libraries/GxEPD-master/GxEPD.h:7:26: fatal error: Adafruit_GFX.h: No such file or directory
compilation terminated.
```

とかのエラーがでたので、

(変更前)

```

#include <GxEPD.h>
```
↓
(変更後)

```

#include <SPI.h>
#include <Adafruit_GFX.h>
#include <GxEPD.h>
```

とするとOK.
LaravelとCarbonのtimezoneが異なるとどうなるのか

「Carbonでタイムゾーンとうまく付き合う」改め「LaravelのtimezoneとCarbonが異なってハマった話」です。

当初、Carbonのせいにしてたのですが、ただの設定ミスでした。

この記事を書いた時、`config/app.php`は以下のようになってました。

```php:app.php
'timezone' => 'UTC',
```

修正後

```php:app.php
'timezone' => 'Asia/Tokyo',
```
----

# LaravelのconfigはUTC、Carbonで`Asia/Tokyo`で扱った場合

```php
$dt = Carbon::create(2018, 3, 1, 0, 0, 0, 'Asia/Tokyo');
$dt->addMonth();
var_dump($dt);
```

これの出力結果はなんと3月29日です。

```bash
class Carbon\Carbon#5356 (3) {
  public $date =>
  string(26) "2018-03-29 00:00:00.000000"
  public $timezone_type =>
  int(3)
  public $timezone =>
  string(10) "Asia/Tokyo"
}
```

# まとめ

タイムゾーン設定はちゃんとそろえましょう。
WebRTCの実験を、ngrokを使って外部サーバー無しで動かそう

# はじめに

WebRTCの実験を行う際には、Webサーバー、シグナリングサーバーが必要になります。[こちらのハンズオン](https://qiita.com/yusuke84/items/de9f0f6d221acec6fc07)でも、自分のローカル環境でWebサーバーやシグナリングサーバーを動かすようになっています。

同一PC上で実験している分には問題ありませんが、違うPC間や、モバイルデバイスとの間で通信を行おうとすると、急に厄介になります。

- ChromeやSafariの場合、localhost 以外では http:// ではカメラ/マイクにアクセスできない
- WiFiとモバイルネットワークなど、ことなるネットワークをまたがっての動作実験ができない
- 同一WiFiでも、カフェやコワーキングスペース、イベント会場などでプライバシーセパレーターが入っていると通信できない

いずれもインターネット上にWebサーバー、シグナリングサーバーを設置することで可能になりますが、少々ハードルが高いと感じることも多いのではないでしょうか。

回避策として例えば次の方法があります。

- 外部サービスを使う
    - WebサーバーにはGitHub Pagesや、FirebaseのWebホスティングを使う
    - [シグナリングにはfirebaseを使ってメッセージ交換を行う](https://html5experts.jp/mganeko/20273/)
- トンネリングツールを使う
    - 例えば [ngrok](https://ngrok.com/) など

今回は後者の ngrok を使う方法を取り上げます。

# ngrok とは

ローカルネットワークで動いているサーバーを、インターネットからアクセスできるように通信をトンネリングしてくれるツール＆サービスです。導入の仕方は例えばこちらの記事が参考になると思います。

- [ngrokの使い方（windows, mac）](https://qiita.com/Esfahan/items/74e71edfe17d9935d47e)

無償、有償で使える機能が異なります。ニーズに応じでプランを選ぶことができます。

- サインアップなし ... http を http/https として公開可能（非公式だがWebSocketも動作）
- サインアップあり ... tcp を公開可能
- 有償プラン ... URLを固定可能

非サインアップ/無償プランの場合は、ツールを起動するたびにURLが割り当てられます。継続的に同じURLで利用したい場合は、有償プランが選択できます。
また、セキュリティ面や安定性の面を考えると、実験用に利用することをお勧めします。

# WebRTCの実験用にngrok を使ってみる

今回はこちらの[WebRTCハンズオン本編](https://qiita.com/yusuke84/items/43a20e3b6c78ae9a8f6c)で使っている[サンプルの最終形](https://github.com/yusuke84/webrtc-handson-2016/tree/handson_step4)を対象にします。

## シグナリングサーバー

node.js でシグナリングサーバーを起動した後、ngrok を使ってWebSocketで使っている3001ポートを公開します。

```
node signaling.js
ngrock http 3001
```

ここでプロトコルとしてhttpを指定しておくと、WebSocketでも使えるようです。
ポートの公開が成功するとコンソール上にURL情報が表示されます。それをメモしておきます。

```
Forwarding                    http://xxxxxx.ngrok.io -> localhost:3001
Forwarding                    https://xxxxxx.ngrok.io -> localhost:3001
```

※ ngrock を起動しなおすとURLが変更されます。

## Webサーバー

### ソースの修正

同様にWebサーバーも公開しますが、今回のサンプルの場合は WebSocket のURLを先ほどメモした情報を使って書き換えておきます。

[webrtc.js の9行目](https://github.com/yusuke84/webrtc-handson-2016/blob/273c63b42ee5847a0ac88ea5c09a2bf73f6822ca/client/webrtc.js#L9)

- before) const wsUrl = 'ws://localhost:3001/';
- after) const wsUrl = 'wss://xxxxxx.ngrok.io/'; 

wsではなく、wssにしましょう。

### Webサーバーの公開

Webサーバーを起動したら、そのポートを公開します。例えば 8888 ポートで動かしている場合は次のようにします。

```
ngrock http 8888
```

シグナリングサーバーと同様にポートの公開が成功するとコンソール上にURL情報が表示されます。もちろんそれもメモしておきましょう

```
Forwarding                    http://yyyyyy.ngrok.io -> localhost:8888
Forwarding                    https://yyyyyy.ngrok.io -> localhost:8888
```

あとは、2台のPCやスマートデバイスから、[https://yyyyyy.ngrok.io](#) に接続すればサンプルを使って通信ができる、ハズです。

# おわりに

WebRTCを実験している最中に困るのは、外部サーバーが必要になるところだと思います。まずはこんな方法でスタートしてみてはいかがでしょうか？

本格的に使うためには、自分でサーバーを立てるかWebRTCプラットフォームのサービスを利用するのことになりますが、そのための判断材料を集めることができると思います。

## 補足

ngrok で公開できるのは、TCPだけのようです。UDPをトンネルすることはできませんので、UDPがふさがったネットワーク間で通信するには、TURNサーバーが別途必要になります。
Raspberry Pi Zero で、Google Assistant SDK「OK Google」エラー

# googlesamples-assistant-hotword で、Illegal instruction 発生


https://github.com/googlesamples/assistant-sdk-python/blob/master/google-assistant-sdk/README.rst

googlesamples-assistant-pushtotalk は動作確認できましたが

googlesamples-assistant-hotword は、Illegal instruction 発生

下記の通り、Raspberry Pi Zero はARM6なんで未サポートでした。

This reference sample implements a simple but functional client for the Google Assistant Library (linux_arm7l and linux_x86_64).

せっかく、Zero買ったのに。動作するような記事も多かったので残念。
chromeの拡張機能管理画面を出力する方法

MarkDown Preview Plus の設定変更をしたかったんだけど、
変更画面を表示できなかったのでメモ

このURLを入力するだけ！
```chrome://extensions/```

他にも方法はあるとは思うけど、とりあえずこれでしのぐ
Google SpreadSheet のシートを Shift JIS の CSV 形式でダウンロードする GAS

「ダウンロード」メニューの CSV (Shift JIS) を選ぶとダイアログが表示され、ダウンロードリンクをクリックすると SJIS 形式で DL できる。
動作確認は Chrome でしかしてない。

download.gs:

```js
function onOpen() {
  const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  const entries = [{
    name : 'CSV (Shift JIS)',
    functionName : 'downloadSJIS_CSV'
  }];
  spreadsheet.addMenu('ダウンロード', entries);
}

function downloadSJIS_CSV() {
  // 開いてるシートのデータを取得
  const sheet = SpreadsheetApp.getActiveSheet();
  const sheetName = sheet.getName();
  const values = sheet.getDataRange().getValues();

  // 文字列のままテンプレートに渡して html を表示
  const template = HtmlService.createTemplateFromFile('download_dialog');
  template.values = JSON.stringify(values)
  template.name = sheetName;
  SpreadsheetApp.getUi().showModalDialog(template.evaluate(), 'CSV (Shift JIS)');
}
```

download_dialog.html:

```html
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
  </head>
  <body>
    <a id="download" href="#" download="<?= name ?>.csv" target="_blank">ダウンロード</a>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.3.7/papaparse.js" integrity="sha256-QvijOmxLUGxTuoxamQikzFRUJ5hFoDOG71tl2M+LULw=" crossorigin="anonymous"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/encoding-japanese/1.0.28/encoding.min.js" integrity="sha256-vvOjQJ89zzmmngTqmXugSMR1JFKbDZuOxHMP3Ia8EdA=" crossorigin="anonymous"></script>
    <script>
      const values = JSON.parse(<?= values ?>)
      
      // CSV 文字列にする
      const csv = Papa.unparse(values)

      // encoding.js を使って csv 文字列を sjis array に変換
      const sjisCodeArray = Encoding.convert(csv, {
        from: 'UNICODE',
        to: 'SJIS',
        type: 'array'
      })

      // sjis array を blob に変換
      const uint8Array = new Uint8Array(sjisCodeArray)
      const blob = new Blob([ uint8Array ], { type: 'text/csv' })

      // URL を a タグにセット
      window.URL = window.URL || window.webkitURL
      document.getElementById("download").href = window.URL.createObjectURL(blob)
    </script>
  </body>
</html>
```

GAS タグついてるけど全然 GAS 書いてない :smirk:

GAS でやってるのはシートの二次元配列を JSON にしてテンプレートに渡すだけで、あとの処理はダイアログで開いた HTML でクライアント側にやらせちゃってる。
自分で言うのもなんだけど、なかなかおもしろいアプローチで他にも使える場面あるんじゃないかと思うし、きっちりメンテされてる JS のライブラリをそのまんま使えるので筋もいいと思う。
Wine; 本物の regsvr32.exe を使う

[目次] (https://qiita.com/Yutaka_Aoki/items/9d38ea98406f4096435b)

# Inside Wine; 本物の regsvr32.exe を使う。

結論から言うと、wine 付属の regsvr32.exe には不具合があり、正常に機能していません。本来なら、登録する COM (ActiveX など) に対応する UUID がレジストリに登録されるはずなのですが、実際には何も登録されないからです。そこで、本家の regsvr32.exe を使います。

## 前提

まず、以下を参照して、

リンク： [本物の regedit を使う] (https://qiita.com/Yutaka_Aoki/items/7070cdcc5b9393389470)

↑ ulib.dll と clb.dll を windows 本家の /windows/system32 から、./wine の system32 にコピーしておきます。それをやっておかないと、本家の regsvr32.exe も正常に機能しないかもしれませんので、絶対に先にやっておいてください。


## 具体的なやり方

例えば、HTML HELP の機能を担う ActiveX であるところの hhctrl.ocx を登録したい時は、こうします :

```
wine /media/XXXXX/WINDOWS/system32/regsvr32.exe hhctrl.ocx
```

/media/XXXXX の部分は、本家の Windows ドライブの Linux におけるパス名になります。


直後に hhctrl.ocx の UUID をレジストリで検索してみると、正常な位置にちゃんと登録されている事を確認できます。

また、この例の場合 実験的にも、MSDN Libary の索引(index)検索が正常に機能するようになることを確認しています。

## 備考

レジストリの検索には、Wine 付属の regedit.exe は使えません。代わりに、本家 Windows の本物の regedit.exe を使います。既出ですが、詳細は：

[本物のregeditを使う] (https://qiita.com/Yutaka_Aoki/items/7070cdcc5b9393389470)

を参照の事。
Wine; windiff.exe, Visual Studio 付属の GUI diff を使う。

[目次] (https://qiita.com/Yutaka_Aoki/items/9d38ea98406f4096435b)

# Inside Wine; windiff.exe, Visual Studio 付属の GUI diff を使う。

結論から言うと、VS 付属の windiff が、Wine でも使えます。

最初の起動と、検索は問題なく行えます。

二度目からは起動できなくなることがあります。

その場合は、regedit を起動して、windiff で検索し、レジストリの中の 「windiff フォルダ」をまるごと削除してしまいます。

すると、最初の起動と同じように起動できるようになります。
新社会人へのVimのすすめ

# 概要
プログラマーになる人は、Vimを習得するとライバルに差をつけれます。

基本動作のまとめはたくさんあるため、ステップ2として重要なことをまとめていきます。

# 重要なこと
## `<ESC>`を押す。
ノーマルモードに戻る癖をつけるのが最重要です。

## ヘルプを極める。
`:h intro` http://vim-jp.org/vimdoc-ja/intro.html#notation
`:h K` http://vim-jp.org/vimdoc-ja/various.html#K

表記については、`:h intro`に書いてあります。調べるのは`K`、戻るのは`<c-o>`です。

## 今までのショートカットは、忘れる。
コピー、検索、保存などです。ショートカットの書き換えは、vimの機能が損なわれます。

## 検索を極める。
`:h /` http://vim-jp.org/vimdoc-ja/pattern.html

他のEditorと同じ感じです。特に難しくないです。ついでに置換と正規表現も極めるといいです。
検索開始地点に合わせる為に、`//e`などで微調整したり。打つのが面倒な場合は、`/a.../`みたいに、`.(ドット)`で楽するのもありです。
また、`s//`で、検索中の文言を置換できるので、正規表現の作成を検索で行ってから、楽に置換することができます。

## 文字選択を極める。
`:h v` http://vim-jp.org/vimdoc-ja/visual.html

最初の選択方法もたくさんあるので、一瞬で理想の選択できます。`o`で、末尾と先頭を入れ変えられるので、微修正も楽です。行選択のほうが使いやすいです。

## 単発繰り返しを極める。
`:h .` http://vim-jp.org/vimdoc-ja/repeat.html

使えるか使えないかで、かなりの差が出ます。置換も単発繰り返しでやったほうが早いことが多いです。

## tabとwindowを極める。
`:h :tab` http://vim-jp.org/vimdoc-ja/tabpage.html#:tabe
`:h :sp` http://vim-jp.org/vimdoc-ja/windows.html#opening-window

たくさんファイルを見れるので便利。開きすぎたら、`<c-w>o`と`:tabo`を使えば閉じます。


# わかりにくいこと
## grep検索を早くしたい。
`:h :vim` http://vim-jp.org/vimdoc-ja/quickfix.html

`noa`をつけると早くなります。 `noa vim // *.vim`。外部grepは設定が面倒なのでお勧めしません。遅いやつは、`git grep`を使っています。

## いろいろな記号
`:h cmdline-special` http://vim-jp.org/vimdoc-ja/cmdline.html#cmdline-special
`:h :range` http://vim-jp.org/vimdoc-ja/cmdline.html#:range
`:h c_CTRL-R` http://vim-jp.org/vimdoc-ja/cmdline.html#c_CTRL-R
`:h v_:` http://vim-jp.org/vimdoc-ja/cmdline.html#v_:

特殊な記号は調べにくいので、ヘルプをまとめてみました。特に、%は調べにくいです。

# 最後に
`:h quickfix` http://vim-jp.org/vimdoc-ja/quickref.html#quickref

これさえ、読めば何とかなります。
Project Euler 43「部分文字列被整除性」

ﾄﾞﾔｧ

# Problem 43 「部分文字列被整除性」
数1406357289は0から9のパンデジタル数である (0から9が1度ずつ現れるので). この数は部分文字列が面白い性質を持っている.
d1を上位1桁目, d2を上位2桁目の数とし, 以下順にdnを定義する. この記法を用いると次のことが分かる.
d2d3d4=406 は 2 で割り切れる
d3d4d5=063 は 3 で割り切れる
d4d5d6=635 は 5 で割り切れる
d5d6d7=357 は 7 で割り切れる
d6d7d8=572 は 11 で割り切れる
d7d8d9=728 は 13 で割り切れる
d8d9d10=289 は 17 で割り切れる
このような性質をもつ0から9のパンデジタル数の総和を求めよ.

```python
from itertools import permutations

def hoge():
    divisors = [ 2,3,5,7,11,13,17 ]
    return sum(int(''.join(p))
               for p in permutations('0123456789')
               if all(int(''.join(p[i:i+3])) % d == 0
                      for i, d in enumerate(divisors, start=1)))

print(hoge())
```

ﾄﾞﾔｧ（ちょっと時間かかるけども。。。
CData API Server ハンズオン（サマリ 編）

# はじめに

本資料は、[CData Software Japan](http://www.cdata.com/jp/)のCData API Server ハンズオン向けの資料です。本ドキュメントをもとに実機にCData製品をインストールして手順に沿って実際に各種ツールやプログラムから使用する事でCData製品の特徴や具体的な利用方法を理解して頂くことを目的としています。

# 前提環境

ハンズオンには以下の環境が必要となります。

※ハンズオン環境のマシンは、下記の前提環境を満たしておりますので本手順は不要です。

- Windowsマシン
- インターネットへ接続可能　※プロキシサーバ経由でのアクセスが必要な場合は事前にご連絡ください
- Windowsの管理者権限が付与されており、プログラムのインストールが可能であること

# 事前準備

ハンズオンを行うマシンにインストールが必要なソフトウェアは以下の通りです。事前にインストールしてください。

※ハンズオン環境のマシンは、下記のソフトウェアを事前にインストールしておりますので本手順は不要です。

- [MySQL Community Edition](https://www.mysql.com/jp/products/community/)
- [Microsoft Power BI Desktop](https://powerbi.microsoft.com/ja-jp/desktop/)
- [Postman](https://www.getpostman.com/) 

# CData Software社、および、CData　API Server製品概要

以下のスライドをご覧ください。

[SlideShare - CData API Server ハンズオン](https://www.slideshare.net/cdatajapan/cdata-api-server-89593261)

# ハンズオン

## RDBからAPIを作ってみよう

- [**RDBからWebAPIをポイント＆クリックで作成**](https://qiita.com/kuwazzy/items/c664570c9d4732a57fac)

## 作ったAPIを使ってみよう

- [**CData API Server で作成したWebAPIにPostmanからアクセス**](https://qiita.com/kuwazzy/items/58ec47afdf0f6d9b23f2)
- [**CData API Server で作成したWebAPIにBIツール(PowerBI)からアクセス**](https://qiita.com/kuwazzy/items/14a46c9159e10eaf75fe)
- [**CData API Server で作成したWebAPIにAngularJSシングルページアプリケーションからアクセス**](https://qiita.com/kuwazzy/items/bc06259f03813f62612d)
- [**(ご参考)Azure Machine Learning に外部データをフィードする方法（CData API Server からOData でフィード）**](https://qiita.com/jonathanh/items/1bd5b5516e4b4b13aa17)

# (ご参考)CData製品ビルド格納パス　※Amazon S3

- [CData ADO.NET Provider for MySQL](https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/HandsOn/20180306/MySQLADONetDriver/HMRC-A/setup.exe)
- [APIServer](https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/HandsOn/20180306/APIServer/KWCC-A/setup.exe)
- [APIServer Driver](https://s3-ap-northeast-1.amazonaws.com/cdatajbuilds/HandsOn/20180306/APIServer/FADC-A_6611_beta.exe)
Wine regedit.exe, 本家の本物のレジストリエディタを使う

[目次] (https://qiita.com/Yutaka_Aoki/items/9d38ea98406f4096435b)

# Inside Wine; regedit.exe, 本家の本物のレジストリエディタを使う。

結論から言うと、本家の regedit を wine で使おうということです。

wine 付属の regedit は、検索に不具合があり、検索しようとすると、左のツリー・ビューが激しく点滅（フリッキング）を起こして、検索にとても長い時間がかかってしまうからです。

## やり方

結論から言うと、ulib.dll と clb.dll をwindows本家の /windows/system32 から、
./wine の system32 にコピーします。

それだけで、本家のregedit.exe が wine で起動できるようになります。

## 詳細

まず、本家の regedit.exe は、デフォルトでは、

c:/WINDOWS/regedit.exe

にありますが、Linux でのパスは、

/media/XXXXX/WINDOWS/regedit.exe

となります。試しに、

```
$ wine /media/XXXXX/WINDOWS/regedit.exe
```

としてみると、次のようなメッセージが出ます。


006b:err:module:import_dll Library ulib.dll (which is needed by L"D:\\WINDOWS\\regedit.exe") not found
006b:err:module:import_dll Library clb.dll (which is needed by L"D:\\WINDOWS\\regedit.exe") not found
006b:err:module:attach_dlls Importing dlls for L"D:\\WINDOWS\\regedit.exe" failed, status c0000135

そこで、ulib.dll と clb.dll を windows本家から、./wine の system32 にコピーするということになるわけです。

なお、ulib.dll と clb.dll は、元々の wine の ./wine の system32 には入っていませんので、上書きの心配なくコピーできます。

実際に、

```
$ wine /media/XXXXX/WINDOWS/regedit.exe
```

としてみると、本家の Windows と見た目まで「そっくり」なレジストリ・エディタが起動します。

そこで、キー名などを検索してみると、不具合も起きることなく、本家 Windows と同じように検索できます。