OmniAICreator/Qiita-1.07M huggingface dataset:
bitnami版のredmineのAll in one Packegeを入れてadminパス忘れた時[Windows]

## 経緯

先日、研究室内のミーティングでタスクと研究予定をガントチャート等にまとめて管理しろと言われました。研究室内における研究及びタスク管理において誰も、何も管理していなかったので、redmineのガントチャートを使おうと思い、導入しました。


## bitnami版のredimineのインストール

redimineのインストールの際には、bitnami版のAll in one Packegeを使用しました。個別にパッケージを入れると、依存関係やバージョンがメンドクサイので、これにしました。

以下のURLから.exeファイルが落とせます。

https://bitnami.com/stack/redmine/installer

## redimineのインストール手順

redimneのインストール手順に関しては、次のURLに詳しく書いてあるので、参考にしてください。しかし、この手順を見ながら出なくても、特段困ることはありません。自分は何も見ないで進めていきました(無心、後で後悔します)。

http://confrage.jp/windows%E3%81%A7bitnami-redmine%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/


## redimineのインストール完了

インストール完了し、redimine1を立ち上げる事が出来たら、管理者権限でログインします。

# 管理者のログイン名とパスワードを忘れる

今、入れたばっかで、インストールの際に決めたUser名とパスを忘れました。笑
ちなみに、一人で笑いました。

笑っていてもしょうがないので、User名とパスを探します。自分はWindowsに入れたので、コンソールを開く際には、スタートメニューからコマンドプロンプトのアイコンの”bitnami redmine stackを使用する”を選択し、起動させます。

起動させると、以下のような画面となります。

```bash

Microsoft Windows [Version 10.0.16299.492]
(c) 2017 Microsoft Corporation. All rights reserved.

C:\Bitnami\redmine-3.4.6-0>

```

パスとログイン名は、railsコンソール上で探し、かつパスは見えなくなっているので、一括変更します。

```rb

C:\Bitnami\redmine-3.4.6-0>cd ./apps/redmine/htdocs
C:\Bitnami\redmine-3.4.6-0/apps/redmine/htdocs> bundle exec rails console production

....

> @users = User.all

> for user in @users

> user.password = '(新しいパスワードをシングルコーテーションで囲む)'

> user.auth_source_id=nil

> user.save!

> end

> quit

....

```


これで、登録してある全てのユーザのパスワードが設定したパスワードになりました。また、自分がインストール時に設定した管理ユーザ名はおそらく@users = User.allで出した時に、"id1"で表示されるはずです。

## 終わり

今後はインストールする際には、気を抜かないようにします。
Hyperledger Fabricのサンプル集fabric-samplesのどれを試してよいかわからないと言う人へ

# この記事のstatus

執筆中

# 概要

Fabric対応バージョン `v1.2.1`

fabric-samples (https://github.com/hyperledger/fabric-samples) ではHyperledger Fabricのサンプル設定/実行例がいくつか載っているが、説明に乏しいのでわかりにくい。

のでまとめてみました。

# 一覧

- basic-network
- first-network
- chaincode
    - abac/go
    - chaincode_example02
    - fabcar
    - marbles02
    - marbles02_private
    - sacc
- chaincode-docker-devmode
- fabric-ca
- balance-transfer
- fabcar: Node.js SDKのサンプル。参考記事: [Fabcarサンプルで学ぶHyperledger Fabric Node.js SDK (v1.2.1対応版)](https://qiita.com/yoshihiro-nnnn/items/a9db142f59f606977b11)
- high-throughput

# 逆引き

- プレーンなネットワークをセットアップしたいなら - basic-network
- チェーンコードのinstall/instantiateと実行を試したいなら - first-network
- チェーンコードのサンプルを見たい - chaincode
    - Goのチェーンコードを見たい - chaincode_example02
    - Node.jsのチェーンコードを見たい - 調査中
    - Private ledgerを試したい - marbles02_private
- chaincode-docker-devmode
- Fabric CAを試したい - fabric-ca

- balance-transfer
- fabcar
- high-throughput
ACS ( IBM i Access Client Solutions ) 1.1.8のプリンタセッション

ACS(IBM i Access Client Solutions) 1.1.8にて、プリンタセッションが利用出来る様になったとの事で試してみました。
## インストール
以下より最新版ACSをダウンロードします。IBM idが必要です。
[ACSのダウンロード](https://www-01.ibm.com/marketing/iwm/iwm/web/download.do?source=swg-ia)
## セッションの構成
- ACSの**［セッション管理機能］**を起動し、**［新規プリンター・セッション］**を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/0780fad5-7315-9675-7a24-b0a20c096e0d.png)
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/c76c119e-8d5b-81e3-444a-2b076cd5507b.png)
- **接続**に、**［プロトコル］**、**［ホスト・コード・ページ］**等を適宜変更します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/835cd5c3-1c57-1075-90ae-0ad5dc599c09.png)
- **接続／OS/400オプション**の**［ホスト印刷変換］［HPTの使用］**を**”いいえ”**にします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/fef98991-effe-f8ee-cc05-d5862e26127f.png)
- **プリンター設定**
    - **［印刷先］**を**”Windowsプリンター”**にします。
    - **［Windowsプリンターの選択］**を**”任意のプリンター”**にします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/77ea6804-f0c9-5885-a6fa-b434bbe3c426.png)

- **ページ設定**
    - **［Java印刷サービスの使用］**を**”はい”**にします。
    - **［最適化］**を**”はい”**にします。（※**”いいえ”**の場合は、Ａ４サイズ縮小印刷時にオーバーフローしました。）
    - **［フォント名］［フォント・スタイル］**で印刷用のフォントを設定します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/100029/e48345c9-02dd-dacc-ed01-b275e1d38672.png)

以上で設定は完了です。
## 最後に

今回は、Canon LBP6710iで印刷しましたが、問題なく印刷が出来ました。
但し、**両面印刷**の設定が、有効にならず１ページずつ発行されてしまいました。両面印刷の制御はWindowsのデバイスドライバが、行っているので問題なく印刷されると期待していたのですが、このあたりは謎です。
php7で, データベースを操作するときの注意点(php5以前の本を写経するとき) mysql_connect()は, undefined function

PHP7で, パーフェクトPHPのひとこと掲示板を作成する際に, mysqlをいじるコードで, いろいろはまる部分があります.

mysql_connect()がないと怒られます.

結果として, `mysql_connect`が, php7では, 使えません.

代わりに, `mysqli_connect`を使えばokです.

また引数の取り方がいろいろ変わっているので, コードがうまく機能しません.

詳しく話す前に,

まずは, 環境から

# 環境

## 本のバージョン
パーフェクトPHPは, 初版第７刷

## OSのバージョン

windows 10
WSLで ubuntu 18.04 を動かしている

## phpのバージョン

```
PHP 7.2.7-0ubuntu0.18.t04.2 (cli)
```

## apache

```
Server version: Apache/2.4.29 (Ubuntu)
```

# mysql_connect()は, undefined functionで怒られる

パーフェクトPHPのp182で, 

> //データベースに接続
$link = mysql_connect('localhost', 'root', '');

という部分があります.

しかし, これは, php7では動きません.

```
 PHP Fatal error:  Uncaught Error: Call to undefined function mysql_connect() in /var/www/study.localhost/oneline_bbs/process_word.php
```

というエラーが出ます.

困ったら公式ドキュメント.

[mysql_connect](http://php.net/manual/en/function.mysql-connect.php)

> (PHP 4, PHP 5)
>
>mysql_connect — Open a connection to a MySQL Server
>
>Warning
This extension was deprecated in PHP 5.5.0, and it was removed in PHP 7.0.0. Instead, the MySQLi or PDO_MySQL extension should be used. See also MySQL: choosing an API guide and related FAQ for more information. Alternatives to this function include:

>mysqli_connect()
PDO::__construct()

と書いてあります.

php4とphp5でしか使えないです. php7では,removeされたと書いてあります.

その代替案として, `mysqli_connect`を使えと書いてあります.

`i`を`mysql`の後ろにつけましょう.


ほかにも,

- `mysql_select_db`
- `mysql_error`
- `mysql_real_escape_string`
- `mysq_query`

もすべてphp7では, 使えません.

`mysql`の部分を, `mysqli`に変えましょう.

このiは, mysql improvedの略かな?

`vim`なら `:%s/mysql/mysqli/gc`で一気に置換すればok.

## 引数がちげーよって怒られる

また本の通りだと, 引数の取り方が変わっているため, 以下のエラーが起きます.

```
PHP Warning:  mysqli_select_db() expects parameter 1 to be mysqli, string given in /var/www/study.localhost/oneline_bbs/process_word.php on line 9, referer: http://study.localhost/oneline_bbs/bbs.php
```

```
PHP Warning:  mysqli_real_escape_string() expects exactly 2 parameters, 1 given in /var/www/study.localhost/oneline_bbs/process_word.php on line 40, referer: http://study.localhost/oneline_bbs/bbs.php
```

公式ドキュメントを見ればすぐわかります.

[mysqli_select_db()](http://php.net/manual/en/mysqli.select-db.php)
[mysqli_real_escape_string()](http://php.net/manual/en/mysqli.real-escape-string.php)

> mysqli_select_db('oneline_bbs', $link)

とパーフェクトPHPには, 書いていますが, 正しくは,  `mysqli_select_db($link, 'oneline_bbs')`

> mysql_real_escape_string($name)

とありますが, 正しくは, `$mysqli_real_escape_string($name)`です.

php7では, `mysqli`がつく関数は, オブジェクト指向的な書き方と, 手続き的な書き方の二つに対応していますので, どちらでもよいです(今回は手続き的な方法でやりました).

本でエラーが出たら公式ドキュメントに当たると大体解決するので重宝しています.
[tips]Gyazoを最速で起動する方法

# 目的 

「Gyazo」に興味がある方のために紹介


# 条件
- 各種アプリのインストール
   - [Gyazo](https://gyazo.com/download?lang=ja)
   - Gyazo GIF
   - [CLCL Lite](http://genjiapp.com/mac/clcl/)

# 目次

- 「Gyazo」を導入するメリット
- 設定方法


# 「Gyazo」を導入するメリット

#### 1. ローカルにファイルが増えていかない

スクリーンショットの画像ファイルってローカルに一旦ダウンロードしないと使えないし、ファイルが溜まっていくのが嫌。

デスクトップ |
----- |
![https://gyazo.com/27e154625c284e0049dae1db906afbc0](https://i.gyazo.com/27e154625c284e0049dae1db906afbc0.png)

##### <font color="Red">gyazoだとクラウドにファイルが置かれるので上記画像のようなことが解消できます！</font>

Gyazo 画像保存場所 |
----- |
![Image from Gyazo](https://i.gyazo.com/062b406b1bf87e9b2b55ce85a918c45f.png)

#### 2. スクショを撮った瞬間すぐにアップロードされて使えるので作業スピードがアップ

#### 3.リモート間での情報共有をスムーズになる

文字だけで情報共有しようとするとなかなか上手くいかないし、無駄にやり取りが多くなると思います。
gyozoを使えば現象をそのまま伝えることができて、情報共有がかなりスムーズにいきます。

slackでの例|
----- |
![Image from Gyazo](https://i.gyazo.com/f0898b6b088207e8079b6527e12f27c6.png)

---

# 設定方法

## 1. 各種アプリをインストールする
- [Gyazo](https://gyazo.com/download?lang=ja)
- [CLCL Lite](http://genjiapp.com/mac/clcl/)

## 2. 「CLCL Lite」で「Gyazo」を最速で起動する

※それぞれのアプリはログイン時に起動して使えるようにしときます

「CLCL Lite」というアプリはダブルタップで指定したアプリを起動することができます。
私は<font color="Red">「option」2回タップで起動</font>するようにしています。



[![https://gyazo.com/be64528be2329e50471607490e04e23f](https://i.gyazo.com/be64528be2329e50471607490e04e23f.png)](https://gyazo.com/be64528be2329e50471607490e04e23f)

## 最後に
使い方は工夫すれば業務でかなり使えるアプリです。(特にテスター)
ぜひ使ってみてください！
会社向けに[Gyazo Teams](https://gyazo.com/teams?lang=ja)もあります。
モックから始まるwebコンテンツ構成案

スクリプト言語とか使わないHTML,CSSオンリーデザイナさんとシステムを構築する時の全体構成案。

## サーバ間通信

RESTfulによるJSONでのやりとり。

## サーバ側言語

好みの問題。

* Scala (静的。速度を求めるならAkka, 求めないならPlay)
* Python3 Flask (動的。サクッと作りたい時)

## クライアント言語

* ES2016以降 (babel等トランスパイラでブラウザに優しくする)

## JSライブラリ

* axios (デザイナさんがどうしてもjQuery使いたかったら折れる)
* Vue.js (.vueコンポーネントにせずhtml,js,css分ける)

## AltCSS

* Stylusで！と圧をかける。LESS等、生CSSでなければしぶしぶ折れる。

## タスクランナー

* gulp使ってたけどnpmで十分そう。SEが率先して用意する。

と思ったらWindowsだとパスのワイルドカードが展開されない罠。

http://neos21.hatenablog.jp/entry/2017/07/14/004416
npm run build でgulp実行する案、頂こう。gulpをグローバルインストールしなくて済むし.binとか参照しなくていいし。

npm run {build・clean・watch}のみできるようにする感じ。
js,css圧縮はローカルではやらず、CI環境で実施(gulpを直接叩く)。

## HTMLテンプレート

* ワンソース案件でなければモックが出来上がった段階で共通項をすぐEJSで纏める。そして教え、布教する。

## ディレクトリ構成

```
├── build           -- coverage等の出力先。.gitignore対象
├── dist            -- 最終成果物の出力先。.gitignore対象
└── src             -- HTMLやrobots.txt等
    └── assets      -- 素材ディレクトリを束ねる
        ├── ejs     -- EJSテンプレート置き場
        ├── img     -- 画像置き場
        ├── script  -- jsやaltJS置き場
        ├── style   -- stylusとか置き場
        └── vendor  -- 外部ライブラリ。jQueryだとjs,css両方あるのでまとめてvendor
```

デザイナさんには予めこの構成でと伝えるとやりやすくなるはず。
request-promise 接続数管理

キャパシティプランニングの観点からソケットに最大値を設定したい場合がある

その場合以下のようなヘルパクラスを作成して管理する

```
const http = require('http')
const https = require('https')

class MyAgent {
    constructor(max) {
        this.http = new http.Agent(),
        this.https = new https.Agent(),
        this.http.maxSockets = max
        this.https.maxSockets = max
    }   
    get(uri) {
        if(uri.match("https://")){
            return this.https
        }else if(uri.match("http://")){
            return this.http
        }   
    }   
}   
```

上記で作ったヘルパクラスを以下のようにrequest-promiseのオプションパラメータであるpoolにいれると最大ソケット数を制限できる

下記のサンプルでは五つ同時アクセスをしているがソケット数は１個に制限できている

```
const rp = require('request-promise')
const myAgent = new MyAgent(1)

const get = async() => {
    const uri = "http://example.com"
    const opt = {
        uri : uri,
        method: "GET",
        timeout: 10 * 1000,
        pool: myAgent.get(uri),
    }
    const result = { success: null, error: null, time: 0 }
    const begintime = process.uptime()
    try{
        result.success = await rp(opt)
    }catch(e){
        result.error = e
    }
    const endtime = process.uptime()
    result.time = endtime - begintime
    return result
}

get().then(console.log)
get().then(console.log)
get().then(console.log)
get().then(console.log)
get().then(console.log)
```
①Raspberry Pi3の環境構築 for MAC

# 準備するもの（周辺機器）
1. MacBook Pro
2. Raspberry Pi 3
3. 16GB以上のSDカード
4. SDカードリーダー
5. USBケーブル 1本
6. LANケーブル 1本
7. USB Ethernetアダプタ

# RASPBIANのダウンロード
最新版のRASPBIANをダウンロードする。
公式
https://www.raspberrypi.org/

今回はwgetでzipファイルとしてダウンロードします。

```
% wget https://downloads.raspberrypi.org/raspbian/images/raspbian-2018-06-29/2018-06-27-raspbian-stretch.zip
```

tarでzipファイルを展開

```
% tar zxvf 2018-06-27-raspbian-stretch.zip
```

# SDカードにイメージを書き込む
Micro SDカードリーダーにSDカードを差し込んでMacに接続

1.SDカードをFAT32でフォーマットします。

```
% diskutil eraseDisk FAT32 RPI /dev/disk1
Started erase on disk1
Unmounting disk
Creating the partition map
...
Finished erase on disk1
```

2.SDカードのアンマウント

```
% diskutil unmountDisk /dev/disk1
Unmount of all volumes on disk1 was successful
```

3.SDカードにイメージを書き込む

```
% sudo dd bs=1024m if=2018-06-27-raspbian-stretch.img  of=/dev/disk1
3+1 records in
3+1 records out
3276800000 bytes transferred in 165.742978 secs (19770370 bytes/sec)
```

# ラズパイ起動
RaspberryPiにSDカードを挿入し、USBケーブルでMACに接続する。
ブート成功=黄緑のLEDが点灯します。
ブート失敗orSDカードに書き込み失敗=赤のLEDのみつきます。

# MacとRaspberryPiをブリッジ接続する
1. MacにUSB Ethernetアダプタを接続し、システム環境設定 -> 共有を開きます。そして、WifiからUSB Ethernetへ共有するよう設定し、インターネット共有のチェックをONにします。
DHCPのIPアドレスが169.254から始まる値になります。

2. Macに接続されたUSB EthernetとRaspberry PiをLANケーブルで接続します。

# sshでRaspberryPiにログインする
ユーザー名はpi、パスワードはraspberry

```
% ssh pi@192.168.2.2
```

RaspberryPi初期設定

```
% pi@raspberrypi ~ $ sudo raspi-config
```

RASPBIANのインストール完了！！

# macからGUIベースでラズパイを操作する

```
% sudo apt-get update
% sudo apt-get upgrade
% sudo apt-get install tightvncserver
% tightvncserver

New 'X' desktop is raspberrypi:1

Starting applications specified in /home/pi/.vnc/xstartup
Log file is /home/pi/.vnc/raspberrypi:1.log

```
macのFinderのメニューから「移動」->「サーバへ接続」で vnc://192.168.2.2:5901 に接続する。

[Raspberry Pi3で湿度と温度を取得する
に続く](https://qiita.com/ksk8/items/ec78e8ed3ab299fc94fa
)
Azure Event Hubs Dedicated Instance について


Event Hubsですが遂にVPNもサポートされましたね。
ちなみに、みなさんはEvent Hub Dedicated Instanceを利用したことがあるでしょうか？Azure Portalからサクッと作成できないため面倒だし使ったことないという方が殆どではないでしょうか？ネットでもあまり情報がなさそうだったので製品チームに確認したことをここで共有します。結論から言うと[公式ドキュメント](https://docs.microsoft.com/ja-jp/azure/event-hubs/event-hubs-dedicated-overview)に記載されている情報以外はStandardと全く同じでした。なのでこの記事には意味がないのかもしれませんが念のため。。。


![image](https://qiita-image-store.s3.amazonaws.com/0/33998/0b01949b-ce65-694e-f025-c59aed6debdf.png)



Q1. 日本リージョンでも利用可能でしょうか？
A1. はい、Standardと同じリージョンにDeployできます。

Q2. Dedicated Instanceを複数配置した場合に共倒れになる可能性はないか。Fault Domain のような仕組みはあるか？
A2. はい、インスタンスはシングルクラスター構成になっており、複数のインスタンスを配置した場合にお互い影響がない構成になっています。

Q3. スケールの変更は可能か？
Q3. はい、Throughput Unitを指定出来ますし、いつでもクラスターの増減が可能です。

Q4. VNET はサポートされるか？
Q4. はい。

Q5. Standardと比較して他にLimitationはないか？
Q5. Geo-Recoveryも含めてStandardでサポートしているものは全部あります。

Q6. Azure PortalからサクッとDeployできるようにする予定はあるか？
Q6. はい。
Xcode9.3でstruct直下にextensionでstructが追加できない

# 概要
xcodeで下記のような時にhogeAPIでAPIというstructが見つからないというエラーが出てbuildが通らない時があったのでメモ

```swift:API.swift
struct API {}
```

```swift:hogeAPI.swift
extension API {
    struct hoge {}
}
```

# 解決策
BuildPhaseのCompileSourceの順番を定義したもの（今回でいうAPI.swift）が一番上にくるようにする。
spring-bootのwebアプリケーションのLogに一意の識別子を付与したい

##動機
webアプリケーションの運用中等
特定のユーザのリクエストだけgrepして挙動を追跡したいと思ったので。

##前提
アプリケーションのlog出力設定済みであることを前提にしています。
詳しく知りたい方は以下を見ていただけると嬉しいです。
[spring-boot AOPでメソッドのinとoutをlogに出力する](https://qiita.com/mijinco0612/items/ac03a3717f2c877ac675)
リポジトリは[こちら](https://github.com/mijinco0612-self-improvement/spring-auth0)

##どうする？

RequestContextHolderからsessionIdを取得するメソッドを作成します。

```java:LoggingAdvice.java
    private String getSessionId() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().getId();
    }
```

上記を利用してLogMassageにSessionIdを追加します。

```java:LoggingAdvice.java
    private void outputLog(JoinPoint joinPoint) {
        String logMessage = "[" + getSessionId() + "]:" + getClassName(joinPoint) + "." + getSignatureName(joinPoint) + ":START:" + getArguments(joinPoint);
        logger.info(logMessage);
    }
```

chromeのシークレットモードを使用してリクエスト投げてみてログを確認してみます。

```bash
2018-07-11 13:23:05 |http-nio-28080-exec-10| [INFO] com.mijinco0612.springauth0.aspect.LoggingAdvice [CD896FA8A5798E84FBF0CDBDDE90E7FF]:class com.mijinco0612.springauth0.controller.api.v1.DemoController.echoApi:STARTtestEchoMessage
2018-07-11 13:23:05 |http-nio-28080-exec-10| [INFO] com.mijinco0612.springauth0.aspect.LoggingAdvice [CD896FA8A5798E84FBF0CDBDDE90E7FF]:class com.mijinco0612.springauth0.controller.api.v1.DemoController.echoApi:END:pongtestEchoMessage
2018-07-11 13:51:08 |http-nio-28080-exec-4| [INFO] com.mijinco0612.springauth0.aspect.LoggingAdvice [5DC68C4A8DB252AE8DAC87AFB94ABFC7]:class com.mijinco0612.springauth0.controller.api.v1.DemoController.publicApi:START:
2018-07-11 13:51:08 |http-nio-28080-exec-4| [INFO] com.mijinco0612.springauth0.aspect.LoggingAdvice [5DC68C4A8DB252AE8DAC87AFB94ABFC7]:class com.mijinco0612.springauth0.controller.api.v1.DemoController.publicApi:END:public
```
[CD896FA8A5798E84FBF0CDBDDE90E7FF]
[5DC68C4A8DB252AE8DAC87AFB94ABFC7]
上記2つのSessionIdが確認できました。これらを利用すれば追跡が簡単になりますね。
聞いても返事がなかったら先に進むダイアログ


```vb

Sub test()
    Dim ret As Long
    With CreateObject("WScript.Shell")

        ret = .Popup("これ似合うと思う？", 2, "ねーねー", vbYesNo)

        If ret = -1 Then
            .Popup "無視とかひどい！", , "怒"
        Else
            .Popup "えーそうかなー？", , IIf(ret = vbYes, "照", "泣")
        End If

    End With
End Sub
```

Excelマクロで作った結構長い処理の途中で、中間結果のメッセージを出したいのだけど、MsgBoxを使うとOKを押すまでそこで処理が止まってしまう。
流しっぱなしで離席して、戻ってきたら終わってる、って感じにしたいので、一定時間表示したら勝手に消えるダイアログが欲しかった。
SendKeysとかを使って無理やり何とかするのかな、と思って色々試したけどうまく行かなかったので、その時は諦めた。
先日、別件でWScript.Shellを使っていた時に偶然目にしたこのPopupとやらで、意外と簡単に書けることを知ったので、メモ。
visudoコマンドでsudoersファイルを編集する

## visudoとは
visudoは**sudoersファイルを安全に編集するコマンド**です。
visudoは複数の同時編集に対してsudoersファイルをロックし、基本的な健全性チェックを提供し、解析エラーをチェックします。

### sudoersとは
どのユーザーが何を実行できるかを記述した設定ファイルのことです。
`/etc/sudoers` に設定ファイルがあります。


### ファイルのロック

```shell-session
$ ll /etc/ | grep sudoers
-r--r-----   1 root  wheel           2299  7 11 12:13 sudoers
$ sudo visudo

(編集中にもう一つの画面から下記を実行)

$ ll /etc/ | grep sudoers
-r--r-----   1 root  wheel           2299  7 11 12:13 sudoers
-rw-------   1 root  wheel           2299  7 11 12:13 sudoers.tmp
$ sudo visudo
visudo: /etc/sudoers busy, try again later
```

`visudo`を実行している間はロックファイルとして`/etc/sudoers.tmp`が作成されています。
この状態でもう一度`visudo`を実行するとエラーが出て編集ができない状態になっていたので、これでファイルがロックされていることがわかります。

### 解析エラーのチェック
manコマンドの日本語訳です。
> visudoは編集後にsudoersファイルを解析し、構文エラーがあれば変更を保存しません。 エラーが見つかると、visudoはエラーが発生した行番号を示すメッセージを表示し、ユーザーは `` What now？ ''プロンプトを受け取ります。 この時点で、ユーザはsudoersファイルを再編集するために `e 'を、変更を保存せずに終了するために` x'を、あるいは変更を終了して保存する `Q 'を入力することができます。 visudoが解析エラーがあると考えている場合は、sudoも同様にエラーが修正されるまで誰も再びsudoできないため、 `Q 'オプションは非常に注意して使用する必要があります。

実際に`visudo` で適当に`a`を追記したところ下記の表示になりました。

```shell-session
$ sudo visudo
>>> /etc/sudoers: syntax error near line 31 <<<
What now?
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save changes to sudoers file (DANGER!)
```

sudoが使えなくなっても大丈夫な環境なので、Qで保存をしてみると`sudo`が使えなくなりました。

```shell-session
$ sudo visudo
>>> /etc/sudoers: syntax error near line 31 <<<
What now?
Options are:
  (e)dit sudoers file again
  e(x)it without saving changes to sudoers file
  (Q)uit and save changes to sudoers file (DANGER!)

What now? Q
$ sudo visudo
>>> /etc/sudoers: syntax error near line 31 <<<
sudo: parse error in /etc/sudoers near line 31
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
$ sudo ll
>>> /etc/sudoers: syntax error near line 31 <<<
sudo: parse error in /etc/sudoers near line 31
sudo: no valid sudoers sources found, quitting
sudo: unable to initialize policy plugin
```

なるほど、`sudoers`の編集を行う場合にミスると`sudo`が使えなくなるので、`visudo`以外で`sudoers`を修正するのは危ないということですね。
今回は検証のためにエラーがある状態でQを選択しましたが、使う場合には気をつけてください。
FuelPHPのログに配列を吐き出す

##やったこと
タイトルの通り

##背景
ボタンクリック時に、ajaxでおよそ80個のポストデータを送信する際に、var_dumpでは表示されないので、取り急ぎLogにはかせることにしたのよ。
結構ajaxでデータをやりとりしているコードが多いので、忘れないようにメモしておく。

##解決策
```
Log::info(print_r($array), true);
```
AndroidのWebView側だけの対応でJavascriptイベントをフックしてaddJavascriptInterfaceで設定したJSメソッドを呼び出す

# はじめに
皆様も参画中のプロジェクトでWebページを編集する権限がなく、どうしてもWebView側でjsやアプリの動作などをカスタマイズしなければならない場合があると思います。
この記事は前述のような方やWebフロントエンジニアに協力を仰げない方々向けのメモです。
（僕の場合は、非協力的なWebフロントエンジニアの対応に四苦八苦し、結局Android側アプリで対応することにorz）

# やり方
例えばjsのhistoryオブジェクトはpopStateイベントリスナーを追加することにより、UrlLoadingを検知できます。
今回は、popStateイベントを利用して、WebViewに登録したJavascriptInterfaceのメソッドを呼び出してみたいと思います。

``` java:SampleActivity.java
// Javascriptを有効に。
mWebView.getSettings().setJavaScriptEnabled(true);
// JavascriptInterfaceを追加！
mWebView.addJavascriptInterface(new JSObject(mWebView), "injectedObj");

mWebView.setWebViewClient( new WebViewClient(){
            // ページにフック用のイベントリスナーを追加する。
            // popStateはpushStateのあとに呼ばれる。
            @Override
            public void onPageFinished(WebView view, String url) {
                mWebView.loadUrl("javascript:window.addEventListener('popState', function (event) { injectedObj.screentype('me') }, false)");
            }
        });
mWebView.loadUrl(mUrl);
```

``` java:JSObject.java
public class JSObject {
    private WebView mWebView;

    public JSObject(WebView webView) {
        this.mWebView = webView;
    }
    // popStateイベント発火したら呼ばれる
    @JavascriptInterface
    public String screentype(String str) {
        Log.d("xxx", "hook " + str);
        return "false";
    }
}
```


これで自由にWebページをフックできるようになりました。どんどんWebページをハックして、自由にカスタマイズしていきましょう！
Raspberry Pi に Python 3.7.0 をインストールする

# 思いつき
職場でCIツールのアラートやSlack、メールの未読に気づかない私です。
できないことがあるなら道具に頼ってしまいたいと考えて、遠く以前に購入してニキシー管チカ[^1]をして遊んだきりの Raspberry Pi 2 Model B を使って LED の視覚的なアラートと音声ブザーを使いたいのです。

## 環境
* Windows 10
    - micro SD カードが読み書きできれば、当然 Mac などでも構わないと思います。
* Raspberry Pi 2 Model B
    - 主役

### 使用したもの
* [NOOBS version 2.8.2](https://www.raspberrypi.org/downloads/noobs/)

* * *

## 作業手順
1. NOOBS を解凍して SD カードに入れる[^2]
1. Raspberry Pi にSD カードを挿入し、インストールする
    - 今回は Raspbian を選択
    - この際、元あった中身のファイルは消える
1. apt-get 周辺のサーバがメンテされなくなったのか使えない<br>そこで apt を利用することにする[^3]

```bash
# 儀式
$ sudo apt update
$ sudo apt upgrade

# ARM 用の準備や SSL や Git や色々
$ sudo apt install -y libffi-dev libbz2-dev liblzma-dev libsqlite3-dev libncurses5-dev libgdbm-dev zlib1g-dev libreadline-dev libssl-dev tk-dev build-essential libncursesw5-dev libc6-dev openssl git


$ Python3 --version
Python 3.5.3

# Python が 3.5.3 だったので 3.7.0 をビルドする
$ wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xz
$ tar -xf Python-3.7.0.tar.xz 
$ cd Python-3.7.0

# ここで ./configure のあとにオプションを指定しているサイトがあるが
# https://bugs.python.org/issue29712 を見る限り不要っぽい？
$ ./configure
$ make
$ sudo make altinstall
$ pip3 install --upgrade pip

$ pip3 --version
pip3 10.0.1
```
]
その後は自分の好みでエイリアスを変更していく

* python -> python2
* (元の) python3 -> python3.5
* python3.7 -> python3

# 今後の課題
* Jenkins なりなんなり、CI ツールから Raspberry Pi に通知を送る方法を調べる
* メールサーバを Raspberry Pi 内に立てると、未読がなくなったときに通知を消す方法が思いつかない
    - Slack なりメールなり、未読がなくなったときのトリガをどうするか



* * *
[^1]: 200V 昇圧はもう触りたくない。
[^2]: うまく認識せず、通常の方法ではフォーマットもできなかったため Windows の diskpart.exe を使用した。
[^3]: これからは apt が標準になるみたいですが、古い記事を参考にしようとすると apt-get が多いみたい。<br>アクセスするサーバの設定を変更したら apt-get でもダウンロードできるとか。

(2018/10/28: 勉強会でドヤ顔しながら「とりあえず `sudo` って入れておけば通るよ！」と言った手前、どれが権限必要なのか再確認したら入れないといけないものに入れてなかったり、入れなくていいものに入れてたりしたから修正

***

(2019/01/23:追記)
以下の2行に sudo を付けよと編集リクエストが届きました。

```
$ pip3 install --upgrade pip
$ pip3 --version
```

手元の環境

ラズパイと同系統の処理ができる
* Windows10 の PowerShell（管理者権限で実行せず）
* MacOS High Sierra
* Ubuntu 18.04

でも本記事の記載とおり愚直に一行ずつ試して、上記3つの環境においてこの部分には権限が必要ないのを確認しているのは先日(2018/10/28)のとおりです。

これらのコマンドで権限が必須な状況・環境・私の勘違いをお教えいただければ幸いです。

* 疑問点
    * `pip3 --version` に`sudo` が必要ならば、`python3 --version` にも `sudo` が必要になるのではないか
    * 実務で`pip3 install spam`するときに `sudo` をつけた覚えがないので、うまいこと権限を与えていないIDEがなんとかしてくれているのだろうか
Windows10 オレオレ証明書の発行

# ClickOnceのFTP発行時に躓いたので自分用のまとめ

## 1.自己認証ファイルの作成

`makecert -n "CN=[1]" -b 01/01/2000 -e 01/01/2100 -r -sv [2].pvk [3].cer`

1.アプリケーションの名前とか
2.pvkファイルの名称
3.cerファイルの名称
[-b]・・・有効期限の開始日
[-e]・・・有効期限の終了日

## 2.ソフトウェア発行元証明形式への変換
`cert2spc [1].cer [2].spc`

1.pvkファイルの名称
2.spcファイルの名称

## 3.証明書と鍵情報の格納

`pvk2pfx -pvk [1].pvk -spc [2].spc -po [3] -pfx [4].pfx -f`

1.pvkファイルの名称
2.spcファイルの名称
3.パスワードの指定
4.pfxファイルの名称
Hyper-V での NAPT 設定

## Hyper-V NAPT 設定手順
Hyper-V にて NAPT(ポートフォワード)を利用する。
いつになったら、これを GUI で出来るようになるんだろうか。

## やり方
### NAPT 仮想スイッチ作成
PowerShell を管理者権限モードで起動し、下記のコマンドを実行する

```powershell:
# New-VMSwitch -SwitchName [任意の名前] -SwitchType Internal
New-VMSwitch -SwitchName NAPT -SwitchType Internal
```

### NAPT 仮想 NIC の VM 割り当て
PowerShell を管理者権限モードで起動し、下記のコマンドを実行する

```powershell:
# 上記の手順で作成した仮想スイッチの"ifIndex"を確認する
Get-NetAdapter

# New-NetIPAddress -IPAddress [IPアドレス] -PrefixLength [ネットマスク長] -ifIndex [対象のifIndex]
New-NetIPAddress -IPAddress 172.16.0.1 -PrefixLength 24 -ifIndex 3
```

### NAT テーブル作成
PowerShell を管理者権限モードで起動し、下記のコマンドを実行する

```powershell:
# New-NetNat -Name "[任意の名前]" -InternalIPInterfaceAddressPrefix [IPアドレス範囲]
New-NetNat -Name "NAPT_172_16_0_0/24" -InternalIPInterfaceAddressPrefix 172.16.0.0/24

# 確認コマンド
Get-NetNat | fl *
```

### 仮想マシンへの設定
Hyper-V 管理画面から設定可能  
NIC に作成した仮想スイッチを設定する  
DHCP では無いので、OS 側で IP を固定する必要あり

### ポートフォワード設定
PowerShell を管理者権限モードで起動し、下記のコマンドを実行する

```powershell:
# Add-NetNatStaticMapping -NatName "[NATテーブルの名前]" -Protocol [TCP|UDP] -ExternalIPAddress [アクセス元IPアドレス] -InternalIPAddress [対象のVMに設定したIPアドレス] -ExternalPort [受付ポート] -InternalPort [フォワード先ポート]
Add-NetNatStaticMapping -NatName "NAPT_172_16_0_0/24" -Protocol TCP -ExternalIPAddress 0.0.0.0 -InternalIPAddress 172.16.0.3 -ExternalPort 6783 -InternalPort 6783
```

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
Windows10 でDocker Engineを動かす方法

# はじめに
2017年に本格的に利用していたDockerを、Windowsで利用するにはいろいろ試行錯誤していました。
結局、UbuntuやRaspbianでしか最近触っていないなという状況で、しばらくWindowsでDockerコマンドを動かしていなかった。

歴史
1. Virtual Box + Docker tool box </br>
 - 時々WindowsUpdateで不安定になる
2. Docker for Windows（Hyper-V）
 - 2017年年末なんかのアップデートで動かなくなった…(´;ω;｀)　
 - いろいろVirtual Boxとかのからみがあると思うけど、調査につかれて放置

ただ、やっぱりメインPCでのDocker利用を捨てきれず
最近、WindowsストアアプリでUbuntuが動くとのことでちょっと試してみた。

# 環境
- Windows 10 Pro
- Ubuntu 16.04 WSL

# 手順

## WSL（Windows Subsystem for Linux）が利用できるようにする
 
WSLが何かわからない人＋設定手順はこの[記事参照](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)
セットアップまで詳しく書いてあります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/207696/23b78d40-3cef-4c1f-ac44-8678c3d98d2d.png)
これをインストールすると
![image.png](https://qiita-image-store.s3.amazonaws.com/0/207696/2de467c2-e66f-9cfb-e0a5-61efad324794.png)
インストール済みって表示されても、しばらくは以下のように表示されるが、少々お待ちください。
初回起動時のみ時間がかかります。
起動したら、ユーザ、パスワードを設定します。
これでUbuntuが利用できるようになります。

## Dockerのインストール

以下のコマンドに従って、Dockerを入れてください。

```bash
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install docker.io
sudo cgroupfs-mount
sudo usermod -aG docker $USER
sudo service docker start
```

このまま、docker利用しようとしても、下記エラーとなりますので、再起動をしてあげてください。

```
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```

## 動作確認

いつものイメージで動作確認をします。

```bash
sudo docker run --rm hello-world
```

こんな簡単にDockerを利用できる日が来るなんてと

以上です。

## 参考記事
[Windows 10でLinuxプログラムを利用可能にするWSL（Windows Subsystem for Linux）をインストールする（バージョン1803対応版）](http://www.atmarkit.co.jp/ait/articles/1608/08/news039.html)
プロトタイプ開発用gemのChankoで、RSpecで機能unitを制御してテストする

私の担当しているRailsの製品で、機能ごとのリリース管理をシンプルにしたいということで、Chankoの導入を検討しました。
結局のところ導入は見送りましたが、ChankoでRSpecを使う点で試行錯誤したメモを残しておきます。

Chankoの概要は[こちらの記事](https://techlife.cookpad.com/entry/2013/04/10/chanko200/)を参考ください。 

Chankoの使い方に関しては、[公式ドキュメント](https://cookpad.github.io/chanko/)を参照ください。

# RSpecで機能unitを制御してテストする

公式ドキュメントではRSpecについて触れてなかったので、自分なりに使い方を検討しました。

既存のテストは、常に新機能がなかったものとしてテストする。
unitごとのテストは`app/spec/units/example_unit`に置いて、この中にあるファイルが実行される時だけunitを有効にしてテストする。
`example_unit.rb`の`active_if`は以下のように書く。

```ruby
# app/units/example_unit/example_unit.rb
active_if do |context, options|
  Rails.env.test? ? false : true
end
```

`app/spec/units/example_unit`のテストが実行される時、`enable_unit(:example_unit)`をbeforeで実行して、unitをactiveにする。
`chanko/test`をrequireする必要がある。

```ruby

# app/spec/units/example_unit/example_unit_spec.rb
require 'chanko/test'

RSpec.feature 'example_unit', type: :feature do
  before do
    enable_unit(:example_unit)
  end

  ...
end
```

# おまけ: Chankoを導入しなかった理由

ActiveJobに対応してなかったから。
Home Assistant (Hass.io) を入れて最初に入れたいAdd-onたち

# Install
手順は公式Web通りですんなりといけたので割愛。

# 管理画面へアクセス
ブラウザで `http://<IPアドレス>:8123` へ。
恐らくは殺風景なページが広がっていると思います。

Google Homeや ChromeCast対応、AppleTVなどのデバイスや
Weemoなどの大手スマートホームHubがあれば、自動で検出しているはず。

# Official Add-onのおすすめを入れる
HA単体ではなくHass.ioを入れたかたは左メニューに`Hass.io`があるはず。
`Hass.io`メニューを開き、`ADD-ON STORE`を開けばアドオン一覧です。

`Configurator`と`Terminal`をおすすめします。
Google Assistantなどと連携する場合はSSL証明書必須になってくるので
`DuckDNS`もしくは`Let'sEncrypt`もよいです。

##Configuratorって？
詳細は[⇒こちら](https://www.home-assistant.io/addons/configurator)
`Hass.io`でいう`/config`の階層でファイルの作成/削除/書換えをwebベースで行えます。多少の文法確認、指摘も行ってくれるためviやnanoでコンソールでyamlファイルたたくより良いです。
HA上のトリガーやサービス、entitiesも一覧にしてくれて簡易挿入が可能。HAの再起動もConfiguratorから指示可能です。
SSHではなくhttpですが、Git commitとpushも対応。
**これなしでは生きられないレベル**

##Terminalって？
詳細は[⇒こちら](https://community.home-assistant.io/t/community-hass-io-add-on-terminal/33814?u=frenck)
Webベースのターミナルです。
Hass.ioのDocker上のターミナル？になるのかな。
起動してsshつなげばLAN内の他の端末やサーバーにも接続可能。
sshでlocalhostにつなげば、HAのターミナルから、Raspbianのターミナルも操作可能です。
HAにトラブル起きて起動しないときなども、このターミナルからログを覗けます。
**出先からも操作したい人にはオススメ**

##DuckDNSって？
詳細は[⇒こちら](https://www.home-assistant.io/addons/duckdns/)
`DuckDNS`という外部サービスでDDNSサービスとの連携です。
そして追加機能として、取得したドメインでの`Let's Encrypt`処理してkeyファイルを保存してくれます。

##Let's Encryptって？
詳細は[⇒こちら](https://www.home-assistant.io/addons/lets_encrypt/)
Let'sEncrypt証明書を有効化して定期的に更新を行ってくれます。
DuckDNS入れて証明書機能を有効にしている場合は不要。
DDNSではなく自前ドメインがあったり、他のDDNS使用する場合はこちらですね。

****
一旦今日はこの辺で。
次回はAddon入れて設定して有効化する流れと、最初にConfiguration.yamlいじるところくらいは書きたいです。
２次元配列の中身を全部移動し、空チェックを行う

#やりたいこと
２次元配列$tのそれぞれの要素から一つづつ空になるまで取り出し、１次元配列にする

#最初にこう組んだ
$tが２次元配列

$dの１次元配列に入れ込む

```php
while(!empty($t)){
	foreach ($t as $key=>&$t_){
		$d[] = array_shift($t_);
	}
}
```

結果無限ループ！
空にならない・・・


#各要素を明示的に空にする
```php
while(!empty($t)){
	foreach ($t as $key=>&$t_){
		$d[] = array_shift($t_);
		if(empty($t_)) unset($t[$key]);	//追加
	}
}
```

出来た

#要点
配列自体も実体として捉えられるのでemptyにはならない

#つぶやき

時々簡単なことに詰まって時間を費やしてしまう。
ちょっと散歩したりしたほうがいい
MySQL 5.6 から MariaDB 10.3 への移行を試してみる 

# MySQL 5.6 のインストール

## SELinux 無効化

```
/etc/sysconfig/selinux
SELINUX=disable
SELINUXTYPE=targeted
```

## firewalld の削除

```
yum -y remove firewalld
```

## MySQL 5.6 / PHP等のインストール

```
yum -y install wget yum-utils php php-mysql httpd
yum localinstall http://dev.mysql.com/get/mysql57-community-release-el6-7.noarch.rpm
yum -y install mysql-community-server
```

## MySQL 起動

```
service mysqld stop
```

# WordPress のインストール

## WordPress用データベースの作成

```
mysql> create database wordpress;
```

## WordPressのダウンロード, 展開, Apacheの起動

```
cd /var/www/html/
wget https://wordpress.org/latest.tar.gz
tar xvf latest.tar.gz
mv wordpress wp
systemctl enable httpd
systemctl start httpd
```

```http://ip_address_server/wp/``` で初期設定ウィザードから初期設定を行います。

投稿を行った状態

![image.png](https://qiita-image-store.s3.amazonaws.com/0/122952/3b31f487-21fe-a48b-da8b-96106d23e9ff.png)



# MySQL 5.6 のデータをバックアップ

mysqldump ですべてのデータをバックアップします。

```
mysqldump --all-databases > dump.sql
```

MySQL 5.6 の datadir は念のため、バックアップしておきます。

```
service mysqld stop
cd /var/lib
mv mysql mysql5.6
```

# MariaDB 10.3 のインストール

MySQL関連のRPMを削除します。

```
yum -y remove "mysql*"
```

[MariaDB Package Repository Setup and Usage](https://mariadb.com/kb/en/library/mariadb-package-repository-setup-and-usage/) に記述されている、以下のコマンドを実行し、/etc/yum.repos.d/ に mariadb.repo を作成します。

```
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | sudo bash
```

MariaDB 10.3 をインストールします。

```
yum -y install MariaDB-server
systemctl enable mariadb
systemctl start mariadb
```

さきほど mysqldump で取得したダンプデータを MariaDB にリストアします。

```
mysql < dump.sql
```

ブラウザで WordPress が利用可能か確認すると、MySQL 5.6の時と同様に稼働していることが確認できました。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/122952/82f4372c-aa28-9efe-ab03-90698885a813.png)

MySQL 5.7 では MariaDB 10.x との乖離がかなり大きいですが、MySQL 5.6 からだと mysqldump でダンプしたデータがそのままリストアできました。
ライブラリ(PopupDialog)のimportがうまくいかない時

# はじめに
 `PopupDialog`
https://github.com/Orderella/PopupDialog
PopupDialogライブラリを入れようとして下記のようなエラーが出たので忘れないようにメモ

## 環境
Xcode9.4
PopupDialog (0.7.0)

### Carthageファイル

```
github "Orderella/PopupDialog" == 0.7
```

### やったこと
XcodeのDerivedData削除
Carthageのキャッシュ削除


## エラー内容

```
Dyld Error Message:
  Library not loaded: /Library/Frameworks/xxx
  Referenced from: /Users/xxx(ユーザー名)/Library/Developer/CoreSimulator/Devices/676A15E4-65EC-4927-8B84-318272031E44/data/Containers/Bundle/Application/95DCDF60-BEBD-45BD-A15E-A56041291A47/dsNativeApp.app/Frameworks/PopupDialog.framework
  Reason: image not found
```

## 原因
PopupDialogの依存ライブラリ`KyoheiG3/DynamicBlurView`を導入する必要があった
依存ライブラリは勝手にCarthageが入れてくれるものだと思っていたがそんなに世の中甘くなかった

### 修正後のCarthageファイル

```
github "Orderella/PopupDialog" == 0.7
github "KyoheiG3/DynamicBlurView" ~> 2.0
```

Carthageをアップデートしてビルドできるようになった
Superfineの管理と部品化のサンプルコード

Superfine の Issues で 「[How to unmount? #136](https://github.com/jorgebucaran/superfine/issues/136)」 とあって、自分が unmount を書くならこうしたいと思ったのがきっかけ。ついでに部品化のコードも書いた。

動いている様子は[こちら](https://glitch.com/~superfineview)からどうぞ。

```html:superfineview.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>SuperfineView</title>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script type="module" src="/script.js" defer></script>
  </head>
  <body>
    <section id="s1"></section>
    <section id="s2"></section>
  </body>
</html>
```

```js:script.js
import * as superfine from 'https://unpkg.com/superfine?module';

export class SuperfineManager {
  constructor(container, template) {
    this.container = container;
    this.template = template;
    this.node = null;
    this.update = null;
  }
  setup(node) {
    this.node = node;
    this.update = () => {
      this.node = superfine.patch(this.node, this.template(), this.container);
      return this;
    }
    return this;
  }
  teardown() {
    // this.update = () => {
    //   this.node = superfine.patch(null, null, this.container);
    //   return this;
    // }
    return this;
  }
  mount(node) {
    this.setup(node).update();
    return this;
  }
  unmount() {
    this.teardown().update();
    return this;
  }
}

export class SuperfineComponents extends Array {
  h(name, attributes, children) {
    this.push(superfine.h(name, attributes, children));
    return this;
  }
}

export class Counter extends SuperfineComponents {
  display(attributes, children=this.state.count) {
    return this.h('h2', attributes, children);
  }
  addButton(attributes, children='+') {
    const handlers = {
      onclick: () => { this.state.count++ }
    }
    const properties = Object.assign(handlers, attributes);
    return this.h('button', properties, children);
  }
  subButton(app, attributes, children='-') {
    const handlers = {
      onclick: () => { this.state.count-- }
    }
    const properties = Object.assign(handlers, attributes);
    return this.h('button', properties, children);
  }
}

export const counter = state => {
  const c = new Counter();
  c.state = state;
  return c;
};

SuperfineManager.prototype.pushTo = function(array) {
  array.push(this);
  return this;
}

const state = {count:0};

const proxy = new Proxy(state, {
  set(target, property, value, receiver) {
    target[property] = value;
    managers.forEach(m => m.update());
    return true;
  }
});

const managers = [];

new SuperfineManager(document.querySelector('#s1'), () => 
  superfine.h('div', {}, counter(proxy)
    .h('h1', {}, 'S1 Counter')
    .display()
    .subButton()
    .addButton()
  )
)
.mount()
.pushTo(managers);

new SuperfineManager(document.querySelector('#s2'), () => 
  superfine.h('div', {}, counter(proxy)
    .h('h1', {}, 'S2 Counter')
    .addButton()
    .subButton()
    .display()
  )
)
.mount()
.pushTo(managers);
```
git のこと備忘録

個人的な git 関連の備忘録です。

## コマンドとか
### ログの AuthorName とか CommitterEmail とかを変更したいとき
歴史の改変です。

```sh
git filter-branch --commit-filter '
        if [ ! "$GIT_AUTHOR_NAME" = "●●●●" ];
        then
                GIT_COMMITTER_NAME="〇〇〇〇";
                GIT_AUTHOR_NAME="〇〇〇〇";
                GIT_COMMITTER_EMAIL="XXX@XXXX.com";
                GIT_AUTHOR_EMAIL="XXX@XXXX.com";
                git commit-tree "$@";
        else
                git commit-tree "$@";
        fi' HEAD
```

* 参考：http://sohtaro.com/blog/2017/06/11/git-author-email-replace/

これは内部ではrebaseとは異なる？動きをしているっぽいので、rebase中にコンフリクトが起きることがないので気持ち的には楽です。
ただし、１コミットづつ実行するので時間がかかります。
ただし、既にリモートへpush済みのブランチに対して変更後のものをpushするのはやばそう。

### ログの AuthorDate と CommiterDate を同じにする
２通りの方法があるっぽいです。

#### 1. `filter-branch` 使う版
上記と同じように `filter-branch` 使います。
特徴は、コンフリクトは起きないけどそれなりに時間がかかるってことでしょうか。

```sh
git filter-branch --env-filter \
  'export GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"' SHA1..HEAD
```

* 参考：https://stackoverflow.com/questions/24819850/use-git-filter-branch-to-correct-committer-dates-in-last-n-commits

#### 2. rebase する版
rebase により実行します。
特徴は、コンフリクトが起きる時があるけど、時間が早いことですかね。

```sh
git rebase --committer-date-is-author-date <コミット番号>
```

ここで、コミット番号を指定すると、そのコミットからHEADに向けて全てが対象となります。

そもそも、時間の変更くらいでコンフリクトが起きることはないのですが、自分の環境ではコンフリクトが起きる場合がありました。そのシチュエーションとは、例えばファイル名を大文字から小文字に変更するなどした場合です。コンフリクトが起きるというか、rebaseがエラーになります。たぶんWindowsが大文字と小文字を区別できないからなのかなとか思ってます。

### ログの日付を変える

```sh
git commit --amend --date="Tue Jly 10 15:59:59 2018 +0900"
```
Vue.js で data や  computed の値の一覧を埋め込んでデバッグを楽にする方法

実機テスト中で [Vue-Devtools](https://jp.vuejs.org/v2/cookbook/debugging-in-vscode.html#Vue-Devtools) が使えない環境だったり、他の人が作ったVueコンポーネントの構造がどうなっているのか、わけがわからないという状況だったり、たんに開発環境ではHTML自体に埋めておいてすぐに確認したいという場合は、次のタグをさくっとコピペするとデバッグがとても楽になります。

slim または pug 形式になっています。

```slim
template(v-if="true")
  table(border=1)
    caption
      | Props
    tr(v-for="(value, key) in $props")
      th(v-text="key")
      td(v-text="value")

  table(border=1)
    caption
      | Variables
    tr(v-for="(value, key) in $data")
      th(v-text="key")
      td(v-text="value")

  table(border=1)
    caption
      | Computed
    tr(v-for="(e, key) in _computedWatchers")
      th(v-text="key")
      td(v-text="e.value")
```

表示はこんな感じですがもっともっとカオスな状況で効果があります。

<p data-height="300" data-theme-id="0" data-slug-hash="jpENoP" data-default-tab="html,result" data-user="akicho8" data-embed-version="2" data-pen-title="Vue.js variables simple display" class="codepen">See the Pen <a href="https://codepen.io/akicho8/pen/jpENoP/">Vue.js variables simple display</a> by Akira Ikeda (<a href="https://codepen.io/akicho8">@akicho8</a>) on <a href="https://codepen.io">CodePen</a>.</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>
Windows 8.1 + Excel 2016 > Ctrl + Alt + vの動作 > コピー元閉じた状態: 「Unicodeテキスト」または「テキスト」のみ

```txt:動作環境
Windows 8.1 Pro (64bit)
Excel 2016
```

### 状況

- コピー元csvファイルがある
- 対象セルの値は`2.176789E-15`
- セル上でコピーを実行
- 新規エクセルファイルで下記のいずれかを実行
    - A. コピー元csvファイルを開いた状態で Ctrl + Alt +* v
        - ==> 「形式を選択して貼り付け」の「貼り付け」項目に「値」などが表示される (参照: 図A)
    - B. コピー元csvファイルを閉じた状態で Ctrl + Alt + v
        - ==> 「形式を選択して貼り付け」にて「Unicodeテキスト」か「テキスト」しか選択できない (参照: 図B)


#### 図A (コピー元開いた状態)
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/dfe183db-f4b7-b40c-4bb5-249d9d2299b4.png)

#### 図B (コピー元閉じた状態)
![qiita.png](https://qiita-image-store.s3.amazonaws.com/0/32870/885f41a4-bede-4ab6-2e05-5ad4e264a13a.png)


### OLEによる貼付け数値の精度

C++ Builderの実装にて、OLEによる貼付けで「値」と指定していた。
指数の値が小数点以下2桁となってしまうが、上記の「コピー元閉じた状態」での貼付けと同等の処理にしているのが原因だろう。
「テキスト」として表示された`2.18E-15`の値として貼付けされているようだ。

C++ Builderの実装にて、コピー元csvファイルを開いた状態で「値」とした貼付けの処理にしたところ、少数点以下2桁よりも多くの数値を保持した貼付けができるようになった。
Literalでjavascriptを呼び出すときの注意

##書きたいこと
 - **Literal**を使用したときの注意点を記載。

##経緯
1. **webapp**作成中ボタンのイベントハンドラー処理でポップアップを表示するためLiteralを使い**javascript**を使用した。
2. ボタンボタンイベント発生時**HTML**で作成した画面が途中から描写されていない状態で**javascript**が発生していた。

##原因
 - **Literal**を使用して**javascript**を呼び出したとき画面表示が**HTML**の上から順番に表示して行って**Literal**の箇所で**javascript**が発生してそれ以降表示しなかったため。
 - まとめると、画面描写がおかしいのではなく、画面描写の途中で**javascript**が、走っている状態。

##対応
・onLoadイベントで実行するようにする。
<ラムダ式有り(IE11非対応)>
 ```
    protected void Button_Click(object sender, EventArgs e)
    {
        string msg = "ボタン";
        Literal.Text =
             "<script type=\"text/javascript\" >"
            +"window.addEventListener('load', () => confirm('" + msg + "'));"
            +"</script>";
    }

<ラムダ式無し(IE11も対応)>

```html
    protected void Button_Click(object sender, EventArgs e)
    {
        string msg = "ボタン";
        Literal.Text =
             "<script type=\"text/javascript\" >"
            +"window.addEventListener('load', function () {"
            +"return confirm('" + msg + "');});"
            +"</script>";
    }
```

今後清書予定あり

処理を教えてくださったalbireoさんに多大なる謝辞を
MongoDB 4.0 を Windows 10 にインストールしてネットワークに晒す方法

何故か MongoDB を Windows 10 で動かす羽目になった。普段は Linux / OSX で仕事しているので、慣れない Windows での作業の奮闘記。

# Server のインストール
MongoDB の HomePage から、'Get MongoDB' -> 'Community Server' -> 'Windows' -> 'Download' でインストーラをダウンロード＆実行

出てくるダイアログのオプションへの返答をすべてデフォルトで進めると、Windows のサービスに MongoDB が登録されて、起動された状態になる。

インストーラ直リン
https://www.mongodb.com/dr/fastdl.mongodb.org/win32/mongodb-win32-x86_64-2008plus-ssl-4.0.0-signed.msi/download

# Compass （MongoDB の GUI モニター）のインストール
動作確認用にインストールしておく。

MongoDB の HomePage から、'Get MongoDB' -> 'Compass' -> 'Platforms を Windows 64-bit(7+)にして' -> 'Download' でインストーラをダウンロード＆実行

# ローカルでの動作確認
Compass を立ち上げ、localhost に 'CONNECT' する。CONNECT できれば OK。

# ネットワークに晒す

## 設定ファイルを編集して bindIp をセット

設定ファイルはデフオルトで下の場所。
C:\Program Files\MongoDB\Server\4.0\bin\mongod.cfg
（サービスの MongoDB Server のプロパティで確認できる）

何らかのエディタを **Windows の管理者権限で実行** して、このファイルを編集する。
( Linux Subsystem で sudo vi みたいにしても書き込みできないよ！）

```
  bindIp: 127.0.0.1
```

となっているところを変更する。自分の IP を'設定' -> 'ネットワークとインターネット' -> 'ネットワークのプロパティ' で確認して（ここでは192.168.1.23だったと仮定する）、後ろに追加する。
ここの文法はちょっとセンシティブで、例えば２つの IP の間にスペースとかあると、サーバーが起動しなくなるので注意。

```
  bindIp: 127.0.0.1,192.168.1.23
```

ウインドウズのサービスから、MongoDB を選んで 'サービスの再起動'

## Windows Defender を設定して TCP の 27017 を通す。

* 'ローカルコンピュータのセキュリティー' の '受信の規則' を右クリックして '新しい規則' を選択
* '規則の種類' を 'ポート' にして、'TCP' で '特定のローカルポート' に 27017 を入力
* '接続を許可する' にチェック
* プロファイルで、ドメイン、プライベート、パブリックの適当なものにチェックを入れる。

## 確認
MongoDB が走ってるマシンに到達できる別のマシンから 

```
mongo 192.168.1.23 
```

でつないでみて接続できれば OK!

# 感想

* MongoDB のインストーラは必要なことは全部やってくれる（Compassをインストールするのを除いては）
* Windows の流儀に慣れてないので設定ファイルの場所を探すのに時間がかかった。
* ウィンドウズのサービスの画面とかファイアウォールの画面とかにたどり着くのはなかなか大変だ。
Windows でドットファイルを作る

## Windows でドットファイルを作る
Windows のエクスプローラでドットファイル（.htaccessなど）を作ろうとすると怒られます。
その場合、ファイル名の後ろにもドットをつけてやると、あら不思議。
ドットファイルが作れます。

例）
.htaccess を作りたい場合、.htaccess. というファイル名にする

「拡張子が変わるけど大丈夫？」的なアラートが出るのでOKすると、ドットファイルの完成です。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
英語は習慣化してスキルアップする

## 1. はじめに

この業界にいる以上、当然ですが様々な場面で英語が登場します。

- 英語のサイトやドキュメントを読むとき
- クラス名やメソッド名を考えるとき
- 英語版対応のアプリを作るとき
 
英語に関するスキルは必須となってきました。
人材を採用するとき等、英語スキル有無を問う企業も多いようです。

![english.jpg](https://qiita-image-store.s3.amazonaws.com/0/247638/28f1a529-7541-0c16-5bdf-3a9c7a9db53a.jpeg)

## 2. 英語を習慣化する

私事ですが、1歳になったばかりの子供がいます。
最近子供が**「あん、ぱん、ぱん」**(＝アンパンマン)と言えるようになってきました^^
その他にも色々な言葉を教えているのですが、これって勉強じゃなく習慣では？と思うようになってきました。
英語も同じで習慣化してしまえば、おのずと身についてくると考えています。

<font color="red">**英語なんて言葉なんだ。こんなものやれば誰だってできるようになる！**</font>
と安河内先生も仰っていますね。

私がここ最近、英語のスキルアップのために習慣化し始めたことをまとめてみたいかと思います。

### 2-1. 英語の動画を見る

私は寝る前や休日の空いた時間等にYouTubeで動画を見ることが好きです。
サッカー関連の動画や自己啓発動画、YouTuberの動画など、合計して1日1時間くらいは見ているかと思います。
視聴する動画の1、2本を英語関連の動画に変更しました。最初は子供向け動画やアニメ動画が分かりやすいかと思います。

### 2-2. 英語の漫画を見る

私は漫画を見ることも好きで、実家には大量の漫画があります。
「ブラックジャックによろしく」も読んだことあるのですが、これの英語版が＜[マンガonウェブ](http://mangaonweb.com/index.html)＞にて無料で見ることができます。私は毎日1話ずつ見るようにしています。
分かりやすい英語が使用されており、内容も面白いのでおすすめです。
英語に限らず漫画から学べることって多いですよね。

### 2-3. 言語設定は基本英語にする

今までは、スマホやIDEの言語設定は基本的に日本語にして使用していましたが、これを英語設定に変更しました。LINE、Instagramあたりは毎日使うし、もちろん英語対応されています。操作慣れているので使用に困ることはほとんどないです。
IDEについても同様ですが、**業務に支障がない範囲で**英語設定にすることが大事ですね^^;

### 2-4. 通勤時間に英語を聞く

私は毎日車で通勤を行っているのですが、往復で1時間ほどあります。
年間にすると約240時間ほど通勤に使っていることになりますね。(つまりは30人日、1.5人月！)
通勤時間は車でTVを流すか音楽を聴いていました。ぼーっと。。
この**ぼーっと**の時間はとても無駄です。通勤時間で流すものを英語に変更しました。
洋楽を聴くんでも全然いいと思っています。ただ**ぼーっと**垂れ流しで聴くのではなく、**脳を使いながら**聴くことが大事です。吸収力は変わってくると思います。多分！

### 2-5. 英和辞典を手元に置いておく

結局は英語知識あるに越したことはないです。
英語の文章中、知らない単語がでてきたら、**重要そうな単語を1つだけ**調べるようにしています。
そのため、サクッと調べれるよう、英和辞典を手元に置いておくようにしています。
というか、スマホにアプリを入れています。
1つ単語が分かれてば、文章の雰囲気が掴めることはよくあります。
全部調べるのは時間がかかりすぎるのでおすすめしません。

## 3. おわりに

この習慣でどのくらい英語スキルがあがるのかは分かりませんが、苦痛に感じないレベルでチャレンジできるかと思っています(笑)

* 毎日続けること
* 勉強と思わないこと
* 英語に慣れること

がとても大事だと思っています。
自分の時間を毎日少しだけ英語に向けてみて、英語を習慣化していきたいと思います。
この記事が少しでも参考になりましたら幸いです。
Bootstrap の使い方のようなもの

# 極めて簡単に Bootstrap を使ってみる

管理画面などで「デザイン工数かけるほどではないけど、完全なノンデザイン HTML も如何なものか・・・」といったときに、割合と重宝します。
「**わずかな記載で、ある程度それっぽく見える**」が重要なポイント。
深く突っ込むと色々できると思うのですが、それは各自で調べて下さい m(_ _)m

## インストール

[http://getbootstrap.com/](http://getbootstrap.com/)から[ダウンロード](http://getbootstrap.com/getting-started/#download)にいくと、zipファイルが落とせるかと思います。

zip ファイルを解凍すると、css、js の２つのディレクトリ(およびその中身のファイル)が出てくると思いますので、DocumentRoot などに設置します。
Linux の場合「wget して unzip して」って手順でもよいかと思います。


## 前提としての HTML

大体、こんな感じかと思います。

```html:
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
    <!-- BootstrapのCSS読み込み -->
    <link href="css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
  <div class="container">
    <div class="row">
      上部のヘッダ各種
    </div>
    <div class="row">
      本体コンテンツ各種
    </div>
  </div>
  <!-- /container -->
<!-- BootstrapのJS読み込み -->
<script src="js/bootstrap.min.js"></script>
</body>
</html>
```

以下、基本的には「本体コンテンツ各種」の中にHTMLを書く前提で色々と書いていきたいと思います。

## 便利な道具：テーブル

```html:
<table class="table table-striped">
```

と書くと、テーブルがストライプな感じで、テーブル行が交互に色付きます。
また

```html:
<table class="table table-hover">
```

と書くと、マウスオーバーしている行の色が変わります(もしかしたら、tbody が必須、かもしれませんのでご注意ください)。

## 便利な道具：form の入力用ギミック

「formを全画面でだだっ広くはしたくない」場合は、

```html:
<form class="col-md-4" action="...
```

といった書き方をすると、ある程度サイズを抑えられます。col-md-4 の数字のところは、１～１２までの任意の数値を入れてください。
４を入れると、大体「左寄せ1/3くらいの幅」になります。

通常の test input は、例えば

```html:
<label>ラベル名</label><input class="form-control" type="text" name="name" value="" placeholder="ガイド用文字列">
```

と書くと

- 「ラベル名」改行「入力場所」というフォーマットになる
- プレースホルダテキストがいい感じに表示される
- その input 要素がアクティブになった時に、ふちが少し青くなる

といった効果があります。

また、ごくごくごく簡単な validate として、アトリビュート値に「required」を入れると「必須要素」になって、未入力チェックくらいは自動でやってくれます。

```html:
<label>ラベル名</label><input required class="form-control" type="text" name="name" value="" placeholder="ガイド用文字列">
```

ラジオボタンの場合

```html:
<div class="radio">
  <label><input type="radio" name="hoge" value="t1">Cookie</label>
  <label><input type="radio" name="hoge" value="t2">URLパラメタ</label>
</div>
```

という風に、全体を「div class="radio"」で囲むときれいな感じになりました。
未チェックですが、checkbox も同じような感じみたいです。

## 便利な道具：リンク用ボタン

「class="btn btn-default"」等のクラスが、Aエレメントだろうが button エレメントだろうが使えるので、ちょっとした実装に重宝します。
btn-default の部分は、デフォルト以外にもあります。

## 文字色

文字色も、class で色々と用意されているので、ちょっとした「エラー表示」などには使いやすいかと思います。
例えば、こんな風に使っていました。

```html:
<div class="alert alert-danger">登録内容にエラーがありました<br><br>
  <?php echo $error; ?>
</div>
```

## まとめ

「細かいデザイン」の調整は、また色々とあるかと思うのですが。
その辺のセンスは筆者には無いのでね。この辺までで。

**とりあえずわずかな手間で、ある程度のデザインがほしい**なんていうときに、細かく便利と思います。

あと、レスポンシブデザイン対応なので、ちゃんと色々組むと、色々なことができるようです。

## 仲間募集中
[弊社](https://www.nittsu-infosys.com/)ではエンジニアを募集中です。インフラからアプリ、ユーザサポートまで幅広く業務を行ってます。
https://www.nittsu-infosys.com/recruit/2019/index.html
[C#] LINQについて忘れないように基礎的な機能をまとめておく

LINQを使いたいと思ってもよく忘れてしまうのでよく使う機能をまとめる

# そもそもLINQとは？
配列、リストなどに使える
繰り返し系の処理が見やすくなる（可読性向上）

# 機能一覧
## 要素絞り込み系
### Select
要素に処理を行ない、その結果を返す

```c#:全て二乗される
var list = new List<int>(){1,2,3,4,5};
list.Select(c => c * c);
//=> 1 4 9 16 25
```

### Where
条件を指定して要素を抽出

```c#:偶数のみ抽出
var list = new List<int>(){1,2,3,4,5};
list.Where(c => c % 2 == 0);
//=>2 4
```

### OrderBy
指定内容で昇順ソートされたデータを返す

```c#:Ageでデータをソート
var array = new[] {
    new{Name = "A", Age = 1},
    new{Name = "C", Age = 2},
    new{Name = "B", Age = 1},
    new{Name = "E", Age = 5},
    new{Name = "D", Age = 3},
};
array.OrderBy(c => c.Age);
//=> {A,1} {B,1} {C,2} {D,3} {E,5}
```

### Aggregate
全ての要素に指定された関数を実行した結果を返す

```c#:Math.Maxを使って最大値の取得
var list = new List<int>() { 1, 2, 3, 4, 5 };
list.Aggregate((current,next) => Math.Max(current,next));
//=> 5
```

## 一つの要素への処理系
### Distinct
重複している要素を除外

```c#:除外
var list = new List<int>(){1,2,2,3,3,3,4,5,5};
list.Distinct();
//=> 1 2 3 4 5
```

## 二つの要素への処理系
### Union
二つの要素をまとめる

```c#:まとめる
var listA = new List<int>(){1,2,3,4,5};
var listB = new List<int>(){4,5,6,7,8};
listA.Union(listB);
//=> 1 2 3 4 5 6 7 8
```

### Intersect
二つの要素の同じ部分の抽出

```c#:同じ部分
var listA = new List<int>(){1,2,3,4,5};
var listB = new List<int>(){4,5,6,7,8};
listA.Intersect(listB);
//=> 4 5
```

## 判定系
### All
全ての要素が条件を満たしているかの判定

```c#:リストの中身が全て10以下？
var list = new List<int>(){1,2,3,4,5};
list.All(c => c < 10);
//=>True
```

### Any
条件を満たす要素が存在しているかの判定

```c#:要素==3が存在する？
var list = new List<int>(){1,2,3,4,5};
list.Any(c => c == 3);
//=>True
```

### Contains
指定した要素が含まれているかの判定

```c#:要素1が存在する？
var list = new List<int>(){1,2,3,4,5};
list.Contains(1);
//=>True
```

## 変換系
### OfType
指定した型に変換
キャストできない要素は除外される

### Cast
指定した型に変換
キャストできない要素が含まれていた場合は例外スロー

### ToArray
配列に変換

### ToDictionary
連想配列に変換

### ToList
リストに変換