OmniAICreator/Qiita-1.07M huggingface dataset:
SonarQubeでテストコードも静的解析するには？

金曜夜の小ネタ。

# 起こったこと
あるモジュールでSonarQubeの静的解析ができない。
下で触れるようにmvn sonar:sonarを使っている。

## 環境
SonarQube 5.4

# 調べたこと

## ログ
"mvn sonar:sonar"を使うシェルスクリプトをJenkins経由で実行していたので、JenkinsのConsole Outputを確認（一部伏せ字）。

```
[ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.0.2:sonar (default-cli) on project XXXXXX: File [moduleKey=XXXXXX, relative=src/test/java/...../XXXXXXTest.java, basedir=XXXXXX] can't be indexed twice. Please check that inclusion/exclusion patterns produce disjoint sets for main and test files -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
```

## 公式ドキュメントやらネットの情報やら

[Narrowing the Focus](https://docs.sonarqube.org/display/SONAR/Narrowing+the+Focus)

- sonar.sourcesで "解析の範囲を特定のディレクトリに制限" (="limit the scope of the analysis to certain directories")できる
- sonar.exclusions, sonar.test.exclusions で、解析から除外するソースコード、単体テストコードを指定できる


[Need clarification on the Inclusion\exclusion pattern](http://sonarqube-archive.15.x6.nabble.com/Need-clarification-on-the-Inclusion-exclusion-pattern-td5026971.html)

>By default Maven plugin will set:
  sonar.sources=src/main/java
  sonar.tests=src/test/java

>Since you have overriden sonar.sources to be "." then indeed test files are indexed twice (once as "main" code and once as "test").

- デフォルトはsrc/main/java, src/test/java
- sonar.sourcesを.に指定したことで、テストコードが2回インデックスされてしまう


[Analysis Parameters](https://docs.sonarqube.org/display/SONAR/Analysis+Parameters)

"the default Maven source code location" とか "the default location for Java Maven projects" とかは以下参照でいいはず。
[Introduction to the Standard Directory Layout](https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html)

# 直したこと

スクリプトの中で"-Dsonar.sources=."を指定していた箇所があったので、それを取り除いた。

```
mvn sonar:sonar -Dsonar.projectKey=XXXXXX -Dsonar.projectName=XXXXXX -Dsonar.projectVersion=XXXXXX -Dsonar.sources=.
↓
mvn sonar:sonar -Dsonar.projectKey=XXXXXX -Dsonar.projectName=XXXXXX -Dsonar.projectVersion=XXXXXX
```

## ちなみに
そもそもなんで -Dsonar.sources=. 付けてたのか。
[Analyzing with SonarQube Scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner)に従っていた。SonarQube導入時に、テストコード書いていない小さいモジュールで試したから、そもそも上記の2回インデックスされる問題が起こらなかった。

```
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.
# This property is optional if sonar.modules is set. 
sonar.sources=.
```
残りのSysprep可能回数を調べる方法

# 概要
WindowsはSysprepの実行回数に制限が掛かっていて、上限に達するとSysprepが出来なくなってしまう。
ただし、Windows8以降は1001回になっているので実質気にしなくても良くなってる。（Windows7までは3回）

# 残りSysprep可能回数を調べる
```bat:Cmd
slmgr /dlv
```
上記コマンドを実行すると↓のような画面が表示される。
![image4504.png](https://qiita-image-store.s3.amazonaws.com/0/97774/0d7e5240-a92d-cfb1-93f2-690a8bc8227d.png)

「残りのWindows猶予期限リセット回数」と「残りのSKU猶予期限リセット可能回数」が残りのSysprep可能回数。
Windows猶予とSKU猶予で何が違うかはわからない...
【R】[shiny] server,を複数ファイルに分けてsource(".R")で呼び出す 

# はいけい

R package:shiny を使って、
<ul><li>csvファイルをアップロード
　　 <li>データセットを整形
　　 <li>整形したデータセットをダウンロード
</ul>
の処理を自動化できるWebアプリケーションを作っています。
# もんだい

server.Rのコードをなるべくシンプルにしたいので、
関数の定義の部分を別ファイルfunctions.Rに分けて書くことにしました。


ファイルの構成
---
![スクリーンショット 2017-08-04 午後11.06.26.png](https://qiita-image-store.s3.amazonaws.com/0/143058/b7d29406-551f-0a7e-29a1-a34718d4dfce.png)

---
それぞれに以下の機能をもたせます

functions.R 
　・csvファイルの読み込み()
　・整形()
　・csvファイルとして出力()
server.R
　・functions.Rの関数を読み込む
　・ui.Rに出力する値を渡す
ui.R
　・csvファイルをアプロードする
　・元データ、整形したデータを表で出力(確認のため)
　・ファイルのダウンロードボタン

ここで、

```:server.R
function(input, output) {

    source("functions.R")
    ...
}
```

と書くと次のエラーが帰ってきます

><font color="Red">'Warning: Error in \<reactive:read_data>: object 'input' not found'</font>



# かいけつ

source()のオプションで、
<strong> local = TRUE</strong>　の指定が必要だったらしい

```:server.R
function(input, output) {

    source("functions.R", local = TRUE)
    ...
}
```

ドキュメントをみると…

```:R_console
?source()
```

<strong>Arguments</strong>
・local	　
>TRUE, FALSE or an environment, determining where the parsed　expressions are evaluated. FALSE (the default) corresponds to the user's workspace (the global environment) and TRUE to the environment from which source is called.

source()で読み込むファイルの置き場所によってこのオプションが必要になるとのこと
working directoryに置いていないスクリプトを読み込みたい場合は、<strong>local = TRUE</strong>を追加する必要あり

今回であれば、設定されたwroking directoryにfunctions.Rがあれば、
最初のコード(local = FALSE)でも大丈夫だったらしいです

## 追記

2017.11.25現在、この記事の内容
CentOS 6 と Software Collections で SyntaxHighlighter

# パッケージをインストールする。
```
$ sudo yum install centos-release-scl-rh
$ sudo yum install httpd git rh-nodejs6-npm
```

# SyntaxHighlighter をビルドする。
```
$ scl enable devtoolset-6 rh-nodejs6 bash
$ git clone https://github.com/syntaxhighlighter/syntaxhighlighter.git
$ cd syntaxhighlighter; pwd
$ npm install
$ ./node_modules/gulp/bin/gulp.js setup-project
$ ./node_modules/gulp/bin/gulp.js build --brushes=all --theme=default
```

# 動作確認する。
```
$ cd /var/www/html; pwd
$ sudo rsync -av ~/syntaxhighlighter/dist .
$ sudo run_init /etc/init.d/httpd start
```

Web ブラウザーを開いて, http://\<FQDN>/dist/ にアクセス,
サンプルが表示されれば OK.

どっとはらい。
Mac OS XにmongoDBをインストール

#構成
MacBook Air (11-inch, Mid 2013)
プロセッサ　1.3 GHz Intel Core i5
メモリ　4 GB 1600 MHz DDR3
macOS Sierra 10.12.5
#brewをインストール
brewが使えない人は[公式サイト](https://brew.sh/index_ja.html)にアクセスして、コマンドを実行
使える人は飛ばしてください。

```/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
```

#mongoDBをインストール
homebrewを使って、mongoDBをインストール

```
brew update
brew install mongodb
```

#mongoDBの確認
mongoDBを起動

```
mongo
```

データベースを使う

```
//データベースを選択
use test_database
//データを保存する
db.test_collection.insert({"name":"yamada","age":20})
//データを取得する
db.test_collection.find()
```

こんな結果が帰って来ればOK

```
{ "_id" : ObjectId("59847cc01516e38618ab3a1b"), "name" : "yamada", "age" : 20 }
```
kotlinでthread

#スレッド
androidはシングルスレッドモデルになっておりシングルスレッドモデルというのは一直線の処理ということです。
しかしそれだとデータをダウンロードする処理を行っているときに他の処理ができなくなってしまいます。
しかしそんなことはなく実際には並行して複数の処理を同時に行っています。
それは別スレッドを使いそこで処理を行っているからです。
ここでkotlinで別スレッドの作り方を。

```kotlin:thread.kt
import java.lang.Thread.sleep
import kotlin.concurrent.thread

private fun a(){
    println("a")
}
private  fun b(){
    println("b")
}
fun main(arg : Array<String>){
    (1..10).forEach {
        thread {
            a()
        }
        thread {
            b()
        }
    }
}
```

```:実行結果
a
b
a
b
a
b
a
b
a
b
a
b
a
a
b
b
a
b
a
b
```

時々割り込み処理になってる
他にもHandlerなどがある
DatabaseRewinderはRAILS_ENV=testでしか動かない

# 背景
Railsのテストをするのにローカル環境とCI環境（Jenkins）でのenvironmentを分けたくて、 `config/environments/jenkins.rb` を作りGemfile等も同様に書き換えていたが、いざ `RAILS_ENV=jenkins bundle exec rspec` をしてみるとDatabaseRewinderがうまく動かなかった。

# 結論
DatabaseRewinderが `test` というenviroment名にしか対応していなかった。

この辺↓
https://github.com/amatsuda/database_rewinder/blob/master/lib/database_rewinder.rb#L34

そもそもRailsの思想自体test環境は1つにすべきということなのだろうか。
単純なミスだったがちょっとハマったのでメモ。
ofxHapPlayer with AVFoundation

# ofxHapPlayerをoF0.9.x+macOS 10.12で使う

masterだとQTKitがあれなのであれですね.

なので素直に[libavformatブランチ](https://github.com/bangnoise/ofxHapPlayer/tree/libavformat)を使いましょう.

基本的には普通に動きますがオーディオが入ってるとアプリ終了時にAudioThreadが怪しいです.
今回はオーディオは要らない使い方だったのでhapファイルからオーディオを抜いて逃げ腰の解決.

## 配布

で, 問題の配布(展示用のマシンで走らせたい, とか.)ですが, ofxHapがdylib使ってるのでdylibなんですね.

なのでRun Scriptの最後に

```bash
# libsnappy

rsync -aved ../../../addons/ofxHapPlayer/libs/snappy/lib/osx/libsnappy.1.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
install_name_tool -change @rpath/snappy/lib/osx/libsnappy.1.dylib @executable_path/../Frameworks/libsnappy.1.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";

# libffmpeg

rsync -aved ../../../addons/ofxHapPlayer/libs/ffmpeg/lib/osx/libavcodec.57.64.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
install_name_tool -change @rpath/ffmpeg/lib/osx/libavcodec.57.dylib @executable_path/../Frameworks/libavcodec.57.64.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";

rsync -aved ../../../addons/ofxHapPlayer/libs/ffmpeg/lib/osx/libavformat.57.56.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
install_name_tool -change @rpath/ffmpeg/lib/osx/libavformat.57.dylib @executable_path/../Frameworks/libavformat.57.56.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";

rsync -aved ../../../addons/ofxHapPlayer/libs/ffmpeg/lib/osx/libavutil.55.34.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
install_name_tool -change @rpath/ffmpeg/lib/osx/libavutil.55.dylib @executable_path/../Frameworks/libavutil.55.34.101.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";

rsync -aved ../../../addons/ofxHapPlayer/libs/ffmpeg/lib/osx/libswresample.2.3.100.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/";
install_name_tool -change @rpath/ffmpeg/lib/osx/libswresample.2.dylib @executable_path/../Frameworks/libswresample.2.3.100.dylib "$TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/$PRODUCT_NAME";
```

を追加しましょう. これで何とかなります.

なんかもっとスマートな方法ある気もするけど取り敢えず.
Gitでコミットする前に文字コードをチェックする（pre-commit）

Gitフックの『pre-commit』で意図しない文字コードのコミットを防ぎます。
Gitが入っていれば恐らく意識せずとも使えるようになっているであろうBashで書いています。

# pre-commitを配置する
対象リポジトリの`.git/hooks`ディレクトリに以下の様な『pre-commit』ファイルを作成し配置します。
`hooks`ディレクトリがない場合は作成します。
『pre-commit』はcommit前に起動してスクリプトを実行してくれます。

```bash:pre-commit
#!/bin/bash

type="text/"
charset="charset=utf-8"

for L in `git diff --cached --name-only HEAD`
do
  if [[ `file -ib $L | grep $type` ]] && [[ ! `file -ib $L | grep $charset` ]]; then
    msg+="$L の文字コードをUTF-8にしてください。\n"
  fi
done

if [ -n "$msg" ]; then
   echo "！！！コミットエラー！！！"
   echo -e "$msg"
   exit 1
fi
```
上記はUTF-8のみコミットを許可したい場合の例です。
許可したい文字コードに合わせてcharsetとメッセージを修正してください。

# スクリプトの説明
## 前提
文字コードのチェックはfileコマンドで行います。
nkfコマンドはインストールされてない事も多く、fileコマンドだとGit Bashでも使えるので。
文字コードを自動変換したい場合はnkfコマンドを使いましょう。

## コミットを許可する文字コードの設定
```bash
type="text/"
charset="charset=utf-8"
```
mimeタイプがtextのファイルをチェック対象にします。
上記はUTF-8のみ許可します。

## コミットファイルの数だけループする
```bash
for L in `git diff --cached --name-only HEAD`
do
  
done
```
`git diff --cached --name-only HEAD`
コマンドを使い、indexとHEADの差分ファイルをループでチェックします。

## fileコマンドで文字コードをチェックする
```bash
if [[ `file -ib $L | grep $type` ]] && [[ ! `file -ib $L | grep $charset` ]]; then
  msg+="$L の文字コードをUTF-8にしてください。\n"
fi
```
`file -ib`
コマンドを使い、ファイルのmimeタイプと文字コードを判定します。
許可したい文字コード以外のファイルをメッセージに詰めます。

## メッセージを表示してエラー終了
```bash
if [ -n "$msg" ]; then
   echo "！！！コミットエラー！！！"
   echo -e "$msg"
   exit 1
fi
```
チェックに引っかかったファイルがあれば表示して、コミットせずにエラー終了とします。
Riotで生成したページをPDFにしようとして

[wkhtmltopdf](https://wkhtmltopdf.org/)は、WebKitエンジンを使ってHTMLからPDFを起こしてくれるソフトウェアです。HTMLやCSSだけでなく、JavaScriptも解釈してくれるし、独立したプログラムということもあって、RailsからでもPHPからでも便利に使えます。

## なぜか処理に失敗

で、RiotでレイアウトしたページをPDFにする必要性が出てきたので、そのままwkhtmltopdfに投げてみたところ、出てきたものはRiotのタグがすっかり抜けたものとなってしまいました。どうしようかと調べてみると、`--debug-javascript`という、JavaScriptの実行状況を出力するオプションがあったので、何かヒントが得られないかやってみました。

```
Warning: undefined:0 TypeError: 'undefined' is not a function
```

とりあえずJavaScriptのエラーらしいことはわかったのですが、原因が判然としないので、「'undefined' is not a function」などを手がかりに検索していきました。すると、[C3.jsというライブラリのIssue](https://github.com/c3js/c3/issues/552)にたどり着きました。

## 解決策

wkhtmltopdfの環境では`Function.prototype.bind`がないためにエラーとなるということで、Polyfillを入れれば解消するとのことでした。

```javascript
Function.prototype.bind = Function.prototype.bind || function (thisp) {
  var fn = this;
  return function () {
    return fn.apply(thisp, arguments);
  };
};
```
アクセス修飾子まとめ～スマホアプリ開発編（Java/Kotlin/Objective-C/Swift/C#/F#）

## はじめに
いろんな言語をまたがって開発しているときに混乱するポイントとして、アクセス修飾子があります。
今回はスマホアプリ開発編として、Android開発で用いられるJava/Kotlin、iOS開発で用いられるObjective-C/Swift、そしてXamarinで使われるC#/F#について、それぞれのアクセス修飾子について調べて、比較表としてまとめてみました。
※Java/C#以外はほとんど経験がないので、間違いがありましたらご指摘いただけますと幸いです

## 比較表
|アクセス修飾子|Java|Kotlin|Objective-C|Swift|C#|F#|
|---|---|---|---|---|---|---|
|**open**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|どこからでもアクセス可能<br>※Swift3で追加|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|
|**public**|どこからでもアクセス可能|どこからでもアクセス可能|どこからでもアクセス可能|どこからでもアクセス可能<br>※ただし別モジュールからの継承とオーバーライドは不可（Swift2まではどこからでもアクセス可能）|どこからでもアクセスが可能|どこからでもアクセスが可能|
|**package**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|同一フレームワーク内からアクセス可能<br>※フレームワーク外ではprivate|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|
|**protected**|同一パッケージ内のクラス＋派生クラスからアクセス可能|継承した同一パッケージ内のクラス＋派生クラスからアクセス可能|同一クラス＋派生クラスからアクセス可能|<font color="Silver">（存在しない）</font>|同一クラス＋派生クラスからアクセスが可能|<font color="Silver">（存在しない）</font>|
|**protected internal**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|同一プロジェクト内のクラス＋派生クラスからアクセス可能|<font color="Silver">（存在しない）</font>|
|**internal**|<font color="Silver">（存在しない）</font>|同一モジュール内でアクセス可能|<font color="Silver">（存在しない）</font>|同一モジュール内でアクセス可能|同一アセンブリ内でアクセス可能|同一アセンブリ内でアクセス可能|
|**fileprivate**|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|同一ファイル内でアクセス可能<br>※Swift3で追加|<font color="Silver">（存在しない）</font>|<font color="Silver">（存在しない）</font>|
|**private**|同一スコープ内でアクセス可能<br>※内部クラスのprivate変数も参照可|同一スコープ内でアクセス可能|同一スコープ内でアクセス可能|同一スコープ内でアクセス可能<br>※Swift2までは同一ファイル内でアクセス可能|同一スコープ内でアクセス可能|同一スコープ内でアクセス可能|
|**指定しない**|同一パッケージ内でアクセス可能|publicと同じ|protectedと同じ|internalと同じ|privateと同じ|publicと同じ<br>※let束縛/do束縛ではprivateと同じ|

何も指定しなかったときの動きがそれぞれ見事に異なるので、注意が必要そうです。

## 参考
[はじめてのKotlin。Javaと比較してみた](http://qiita.com/hituziando/items/fa2dc4097b24ab78276e)
[Swift 3からのアクセスコントロール](http://qiita.com/hironytic/items/6cc68ca93b428ba9194e)
[Objective-C アクセス指定子](https://akatukisiden.wordpress.com/2011/09/26/objective-c-access-modifier/)
DynamoDBで件数だけ取得するサンプル


# 概要

DynamoDBのデータの件数を数えるとき、scanやqueryで検索した結果をプログラムで数えると件数が多いときに遅くなってしまう。selectオプションを使用することにより件数のみ早く取得することが可能。

# PHP

## 準備

+ aws.pharをダウンロード

https://github.com/aws/aws-sdk-php/releases

今回（2017/08/04）のバージョンは、Version 3.32.3

## サンプル

下記を設定する。

+ REGION
+ KEY
+ SECRET
+ TABLE NAME
+ INDEX NAME（必要な場合）
+ SEARCH KEY　検索するキー
+ SERCH VALUE 検索する値

aws.pharと同じディレクトリに置いた。

```dynamo_count.php
<?php

require_once('aws.phar');

use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\Exception\DynamoDbException;

$client = new DynamoDbClient(array(
  'version' => 'latest',
  'region'  => '<REGION>',
  'credentials' => [
    'key'     => '<KEY>',
    'secret'  => '<SECRET>',
  ]
));

$result_count = 0;
$LastEvaluatedKey = null;

do {
  $arg = array(
    'TableName' => '<TABLE NAME>',
    'Select' => 'COUNT',
    'ScanIndexForward' => false,
    'IndexName' => '<INDEX NAME>', // 必要な場合のみ
    'KeyConditions' => array(
      '<SEARCH KEY>' => array(
        'AttributeValueList' => array(
          array('S'=>'<SEARCH VALUE>') // Sの場合
        ),
        'ComparisonOperator' => 'EQ'
      ),
    ),
  );

  if($LastEvaluatedKey){
    $arg['ExclusiveStartKey'] = $LastEvaluatedKey;
  }

  $result = $client->query($arg);

  $result_count = $result_count + $result['Count'];
  $LastEvaluatedKey = $result['LastEvaluatedKey'];

} while ($LastEvaluatedKey);

print_r($result_count);

```

結果は1MB制限があるので、ExclusiveStartKeyを指定して繰り返して取らないと正しい値が取れない。

## 実行

```
$ php dynamo_count.php
```

## Scanの場合

scanの時は、下記の部分を変更


```
$arg = array(
    'TableName' => '<TABLE NAME>',
    'Select' => 'COUNT',
    'ScanIndexForward' => false,
  );
```

```
$result = $client->scan($arg);
```

# AWS CLI

上記のオプションとちょっと違うけどメモ的に書いておく。

```query
$ aws dynamodb --profile <PROFILE> query --table-name <TABLE NAME> --key-condition-expression "#key = :key" --expression-attribute-names '{"#key": "<SEARCH KEY>"}' --expression-attribute-values '{":key": {"S":"＜SEARCH VALUE＞"}}' --index-name <INDEX NAME> --select COUNT
```

```scan
$ aws dynamodb --profile <PROFILE> scan --table-name <TABLE NAME> --select COUNT
```

こんなのが返ってきます。

```
{
    "Count": <件数>,
    "ScannedCount": <件数>,
    "ConsumedCapacity": null
}
```
git で remote master ブランチへのプッシュを禁止する


設定にあたって、意外とあちこちから情報を集めたので、まとめます。

## 新たに clone されたリポジトリから master へプッシュできないようにする

フォルダをつくります

> mkdir ~/.git_template/hooks

hook シェルを編集します

> vi ~/.git_template/hooks/pre-push

```~/.git_template/hooks/pre-push

#!/bin/bash

while read local_ref local_sha1 remote_ref remote_sha1
do
  if [[ "${remote_ref##refs/heads/}" = "master" ]]; then
    echo "Do not push to master branch!!!"
    exit 1
  fi
done
```

実行権限を付与します

> chmod +x ~/.git_template/hooks/pre-push


git clone した際に、各リポジトリにコピーされるようにします
> git config --global init.templatedir ~/.git_template/


## 既存のリポジトリでも master へプッシュできないようにする
設定をコピーします
> cd hogerepo
> cp ~/.git_template/hooks/pre-push ./git/hook/pre-push


## 挙動
master ブランチで push しようとすると、こんなエラーになります。

```
$ git push -u origin master
Do not push to master branch!!!
error: failed to push some refs to 'git@github.com:hoge/hogerepo.git'
```

もちろん、マージはできます！

## 注意点

各人が設定する必要があります。
誰かが設定してプッシュしとけばみんな同じ設定になるわけじゃないです。

## 参考情報
[masterブランチにpushさせないようにするフック](http://ganmacs.hatenablog.com/entry/2014/06/18/224132)
[master への push を禁止するローカル git hook の正しい書き方](http://thinca.hatenablog.com/entry/20150306/1425639218)
Python3_PyGame で2Dゲーム制作

#Python3とPyGameでゲーム制作メモ ( part1, 準備編 )
Python3の勉強ついでにゲーム制作をしようと思ったが，WWW上には古い情報が多く，現時点での最新版の**Python3**で作るというものが少なかったのでメモ．内容は，参考文献[1]を用いて勉強したもの．
前提として，python3はすでにインストールされているものとします．

####開発環境
・macOS Sierra(10.12.5)
・Python(3.6.2)
・PyGame(1.9.3)

####参考URL
・Python公式：https://www.python.org/
・PyGame公式：https://www.pygame.org/news
・PyGameドキュメント：https://www.pygame.org/docs/
・PyGame Wikipedia：https://ja.wikipedia.org/wiki/Pygame

##PyGameインストール
まずはインストール
```pip install pygame```

一応ちゃんとインストールできているかinteractive modeで確認
```$ python```

```
>>> import pygame
>>> pygame.ver
'1.9.3'
>>> exit()
```
きちんとバージョン情報が出たのでOK！

##ウィンドウの表示

```pygame_sample.py
#_*_coding:utf-8_*_                                                                                                                     
#ウィンドウを表示する                                                                                                                   
import sys
import pygame
from pygame.locals import *

pygame.init() #pygameの初期化                                                                                                           
screen = pygame.display.set_mode((400, 300)) #ウィンドウの大きさ                                                                       
pygame.display.set_caption("PyGame") #タイトルバー                                                                                      

# mainループ                                                                                                                            
def main():
    while True:
        screen.fill((0,0,0)) #ウィンドウの背景色                                          
        #イベントの取得
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit() #閉じるボタンが押されたらプログラムを終了                                                                 
                sys.exit
        pygame.display.update()

if __name__ == '__main__':
    main()
```
実行すると・・・

![window.png](https://qiita-image-store.s3.amazonaws.com/0/76122/311ffcf5-e135-e3f7-be09-11e3d34933ca.png)

ウィンドウが表示される！

※ ただし，mac版ではインストールしたpythonのパッケージによってターミナルがキー操作を独占してしまい操作ができなくなったり，ウィンドウがターミナルの裏に表示されてしまい前面に出ないなどのバグが発生します．python公式インストーラやHomebrewを用いてインストールすればきちんと動作します．pyenvを用いてインストールしたものだと上記のバグが発生することが確認されています(Anacondaは未確認)．

次は画像の表示です．
[Python3とPyGameでゲーム制作メモ(part2, 画像の表示)](http://qiita.com/ken_3982/items/ad385329ee28535e84ce)
　
　
####参考文献
1. 田中賢一郎 (2017) 「ゲームを作りながら楽しく学べるPythonプログラミング」 インプレスR&D
KotlinでAndroidのpublic methodをoverrideするときに気をつけること


# TL;DR (長い3行で)
- Kotlinで`onActivityResult()`をoverrideして，`startActivityForResult()`したら，
- Frameworkが`onActivityResult()`の呼び出しに失敗してCrashする．
- Platform型(`Intent!` == `Intent` or `Intent?`)を意識して引数の型を変えないとダメ．

# JAVA→Kotlin化でやったこと
もともとあったAndroid JAVA AppのActivityをKotlinに書き換えていたときのこと．
Runtime Permission解決のくだりで，↓ のようなKotlin CodeにしてSettingsを呼び出しています．

```kotlin:Activity.kt
overide fun onResume() {
    ....
    if (!Settings.canDrawOverlays(this)) {
        val intent = Intent(
                Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                Uri.parse("package:" + PACKAGE_NAME))
        startActivityForResult(intent, REQUEST_CODE)
    }
    ....
}
```
Settings終了後の`onActivityResult()`も ↓ のようにKotlin化しました．

```kotlin:Activity.kt
override fun onActivityResult(requestCode: Int, resultCode: Int, intent: Intent) {
    ....
    if (requestCode == REQUEST_CODE) {
        if (!Settings.canDrawOverlays(this)) {
            finish()
        }
    }
    ....
}
```

#起こる問題
実際に上のCodeを実行すると，
App起動→SettingsApp起動→Java Crash
になります．

Crash Logは ↓ のようなもの．

```
D/AndroidRuntime( 6186): Shutting down VM
E/UncaughtException( 6186):
E/UncaughtException( 6186): java.lang.RuntimeException:
        Failure delivering result ResultInfo{who=null, request=100, result=0, intent=null} to activity {package/class}:
        java.lang.IllegalArgumentException: Parameter specified as non-null is null:
        method kotlin.jvm.internal.Intrinsics.checkParameterIsNotNull, parameter intent
```

#解決のためにやったこと
Logにかかれているとおり，`non-null`型に`null`を入れようとして`onActivityResult()`の呼び出し時に実行時Errorになっている模様．
`onActivityResult()`の引数の型を

override fun onActivityResult(requestCode: Int, resultCode: Int, intent: **Intent?**)

としてあげれば正しく動作するようになります．
(Kotlin側で引数を使うときはnull check等でnon-null化は必要になりますが)

#まとめ
Platform型の話をKotlin勉強会で聞いていたので，そこまで戸惑わなかったですが，
初見でこのError見たらけっこうハマってたかもしれません．

Android StudioのJAVA→Kotlin Convert使えばこのへんもかしこくConvertしてくれるのかな．

---///
プログラミングを独学するにはどうしたら良いか

知人からタイトルの様に質問されて、自分なりに回答したものを共有しようと思います。

自分はプログラミングが全くわからない状態で開発部に配属されて2年間、フリーランスで2年間、計4年間iOSアプリを開発してきた経歴を持っています。
独学だったか？　と言われると難しいところですが、共有させていただきます。

##1. ひたすらググる

「iOS アプリ カメラ 開発」だったり、エラーの時に出てくる英語の文章をそのままコピペして検索したりなど、ひたすらググっていました。
これは今も変わりません。エンジニアはググれる力がないと生き残れません。
その際によくQiitaやStackOverflowなどがよく出てくると思います。日本語版もありますがStackOverflowでは基本的に英語なのでちょっと敬遠するかもしれませんが、よくお世話になっています。ちなみに自分は英語がそんなに得意ではないです。

##2. 参考書や動画は後からで良い

ドットインストールというプログラミング学習サイトを見たり、分厚い参考書を買ったこともありますが入門時にはそんなに必要ないと思います。
大体分厚い参考書をやりきれず挫折します。僕も読みきっていない参考書がいっぱいあります。
最初の頃はひたすらググっていました。

##3. それでもわからないときは人に聞く

ひたすらググる、とは言ってもやっぱりわからないときはどうしても出てきます。
僕の場合は職場だったり友人に聞くことができました。そういう環境でない場合は

- Stack Overflow
- teratail

などの技術専門Q&Aサービスで聞いてみるのも良いかもしれません。
ちなみに自分は1度だけ質問して回答が返ってきたことがあります。結果的には回答は解決には至らなくて自分で解決することになったのですが。

あとはお金をかけていいならTechCampだったりTechAcademyだったりのプログラミングスクールを利用するのも良いかもしれません。
ちなみに上記の2つではないのですが、会社で通わせてもらったプログラミングスクールで、iOSではなくPHPを学んだのですが、内容が古く結局ググって勉強した記憶があります。
なので、ちゃんと現場で通用することが学べるかがプログラミングスクールを選ぶコツかもしれません。

##4. 目的意識を持つこと
自分がエンジニアになったきっかけは開発部に配属されたからでした。
なので、危機感で成長しました。独学したいと考えている方はどうしてプログラミングを勉強したいのか、という目的意識を今一度考えてみると良いかもしれません。
独学はやっぱり大変なので強い目的意識が必要だと思います。

##5. 情報収集
twitterでエンジニアをフォローしたり、はてなブックマークのテクノロジーカテゴリでひたすら技術関連の情報を漁っていました。最初は興味が湧く記事からわからないなりに読んでいって、次第に分野も広がっていきました。
これは今も続けています。

##6. とにかく手を動かすこと
規模の小さいアプリでもいいのでとにかく手を動かして開発していました。
なるべく自分の興味に近かったり役立つものが良いですね。例えばゴルフに興味があるのなら「アプリからゴルフをしている自分を録画する」みたいに最小限で作って徐々に「シェア機能」「ブックマーク機能」などを足していく、というふうに手を動かすと良いかもしれません。

自分は社会人1年目の頃はプライベートでもアプリを作ってAppStoreに2本公開していました。
手を動かすこと、それを人に見せることはとても大事です。

#まとめ
- ひたすらググること
- 参考書や動画は後からで良い
- どうしてもわからないときは人に聞く（技術系Q&Aサービス使うのが良いかも）
- 目的意識を明確にすること
- twitterやはてなブックマークで情報収集
- とにかく手を動かすこと。興味があったり役に立つものを、小さい規模から徐々に大きくして人に見せること
Emacs で字を大きく表示するための「 Sakurahasi 」というパッケージを作りました．





「鬱」とか「薔薇」という字の細かい部分を確認したいことはありませんか？ フォントの細かい部分をたまにはじっくり鑑賞したくなりませんか？

今回そのようなニーズに Emacs で応えるための「 Sakurahasi 」というパッケージを作ったのでご紹介します．なお，この名前は静岡鉄道の「桜橋」駅からもらっています．

https://github.com/idaisukee/Sakurahasi

使い方は単純です．拡大したい部分をリージョンにして， `Sakurahasi-cmd` を実行してください．すると別ウィンドウに字が大きく表示されます．

![Screenshot](https://lh3.googleusercontent.com/Is5g8HuHrjk8CFyZw5_UwK15XTbd4wKDCAk_1T9KZIGVNdv2xI1ebWhDu87oOWfpGkpdtxUie_NSjJ6IklhOMFGoNNh1osr13pthZOcm2ikchsXcVEqcq0XQ7Q6fZnWxdQg-qNbh0ILrnNGju1csKrcXGDifd2XdNfzuB8U9pU7bwa6vWHY4knAjMSyYB9vF-VBwIr_zkgdlZA2lTh7BB0PLY3smmwScP9GB0nh15yPWsmNgcEQUzH5PGxKJDElHYAjeKlhuewA-YQ5AUYH6YF_ZfKFkevSZ6qUPEXyw_Yg9SSMlzf6y_0h9wzUl3uFD3Kf5hegQWYpokAGMwmfZcFzqW1M8nkYLPslmioM38eL1MomSaWjDuAtNW4B8P3AKg9FClUv-MyB25SFWX3JNK-S0nsdeU2OMQNLqLG3kjSLVi048TncFgYPcrTbEi1KaT0GdI1gLzz6_KBRTtejs2ToVRPTCY-l8_RVi6qWDhiKFIgnLVfvWrtx_3YC7IcH2Vrw3C8R0EIL-KzdS4s4dlHcYFvbiI7TLKZE-nYgUX4YVTReV_vkDVzz0UesjrAqCEDyDCcqP2OC1Z15YITa4W8oB46p1_3nDjLPmrxqA7ApGm281UGBCA12s=w791-h441-no)

この別ウィンドウを消すコマンドは特に用意していません．なので， `popwin.el` なり `winner` なりお好みの方法で消してください．
emacsでインターネットの辞書を引く

emacsから英和辞典や国語辞典などの辞書を引きたい。フリーの辞書コンテンツではなくちゃんとした辞書が使いたい。
emacsで使える辞書ツールには[SDIC](http://www.namazu.org/~tsuchiya/sdic/)や[Lookup](http://lookup.sourceforge.net/docs/ja/)などがある。しかしSDICはフリーの辞書を使うので、やはり辞書コンテンツが貧弱。Lookupは[EPWING](https://ja.wikipedia.org/wiki/EPWING)の辞書が使えるが、市販の辞書コンテンツを買うにはコストがかかる。[Weblio](http://www.weblio.jp/)などのインターネット上の辞書サイトを使えば市販の辞書コンテンツが使えるが、いちいちFirefoxなどのWebブラウザでサイトを開いて調べたい語を打ち込むのは面倒なので、emacsの閉じた環境でネット上の辞書が引きたい。

[dic-lookup-w3m](https://osdn.net/projects/dic-lookup-w3m/)をインストール。[MELPA](http://melpa.org/)や[el-get](https://github.com/dimitri/el-get)にもある。
dic-lookup-w3mを使うには[emacs-w3m](http://emacs-w3m.namazu.org/)と[w3m](http://w3m.sourceforge.net/)が必要。emacs-w3mは、サイトからダウンロードできる.tar.gzファイルは古すぎるので、cvsでコピーするかMELPAやel-getでインストールする。
w3mのWindows用のバイナリは[cygwin](http://cygwin.com/)にパッケージがある。または[w3m for windows](http://hp.vector.co.jp/authors/VA052357/w3m_w32.html)でバイナリーを配布している人がいる。

``` init.el
(autoload 'dic-lookup-w3m "dic-lookup-w3m" "w3mで辞書を引く" t)
(setq w3m-key-binding 'info)
```
`M-x dic-lookup-w3m`で起動する。`Which engine? : `と聞いてくるので、補完リストから辞書を選ぶ。たとえば`ej-weblio`。
`ej-weblio search: `と聞いてくるので、検索したい語を入力すると辞書を引いて結果を表示する。起動する前にカーソルがあった場所の単語が自動的に挿入されているので、それでよければ単にEnterキーを入力する。

いちいちコマンドを打ち込むのは面倒なので、よく使う辞書サイトを適当なキーにバインドする。

``` init.el
(global-set-key "\C-cc" (lambda()(interactive)(dic-lookup-w3m "ej-weblio")))
(global-set-key "\C-cj" (lambda()(interactive)(dic-lookup-w3m "jj-weblio")))
```
![キーバインドを設定してC-c cと入力したところ](https://qiita-image-store.s3.amazonaws.com/0/40128/124b7367-ef54-061e-43f5-c5d531fd9e12.png)
emacs-w3mで[Wikipediaの記事](https://en.wikipedia.org/wiki/Teriyaki)を開き、キーバインドを設定してC-c cと入力したところ

![検索結果](https://qiita-image-store.s3.amazonaws.com/0/40128/6304ec64-d233-d37e-a702-ff2606fb67a3.png)
検索結果。広告やヘッダなどが表示されない。

以下のように設定すればマウスのダブルクリックだけで辞書が引ける。

``` init.el
 (global-set-key
 [double-mouse-1] (lambda()(interactive) (dic-lookup-w3m "ej-weblio" 'word))))
```
細かな設定はREADMEを参照。
SKStoreReviewController まとめ

※ ブラックボックスなところが多いので情報あったら教えてください

# これは何

Appleが公式で用意したレビュー訴求用のAPI
iOS 10.3以降で使える

# これを使う理由

Appleのレビューガイドラインより
https://developer.apple.com/app-store/review/guidelines/#objectionable-content

>
1.1.7 App Store Reviews:
Use the provided API to prompt users to review your app; this functionality allows customers to provide an App Store rating and review without the inconvenience of leaving your app, and we will disallow custom review prompts.
> （Google翻訳：提供されたAPIを使用して、ユーザーにアプリのレビューを促します。 この機能により、お客様はApp Storeの評価と提供をアプリを離れることの不便さなしに行うことができ、カスタムレビューのプロンプトは許可されません。）

要はオリジナルのレビュー訴求は認められなくなり、公式で用意されたものを使わないとリジェクトされる可能性が高くなった

レビュー訴求するならもうSKStoreReviewControllerを **使わないといけない**


ただし
https://developer.apple.com/documentation/storekit/skstorereviewcontroller/2851536-requestreview

>
When you call this method in your shipping app and a rating/review request view is displayed, the system handles the entire process for you. In addition, you can continue to include a persistent link in the settings or configuration screens of your app that deep-links to your App Store product page. To automatically open a page on which users can write a review in the App Store, append the query parameter action=write-review to your product URL.
（Google翻訳：送料アプリでこのメソッドを呼び出し、評価/レビュー依頼ビューが表示されると、システムはプロセス全体を処理します。 さらに、App Storeの製品ページに深くリンクしている設定や設定画面に、永続的なリンクを引き続き含めることができます。 ユーザがApp Storeにレビューを書くことができるページを自動的に開くには、クエリパラメータaction = write-reviewを商品URLに追加します。）

AppStoreのレビュー投稿画面へのDeepLinkは設置してOKだそう

# SKStoreReviewControllerによるレビュー訴求の注意点

https://developer.apple.com/ios/human-interface-guidelines/interaction/ratings-and-reviews/
より

- ユーザは設定でレビュー訴求をオフにできる
- ユーザあたりアプリごとに最大365日に3回まで表示
- 必ずレビュー訴求が表示されるわけではない

# 実装

レビュー訴求したいところで

```swift
SKStoreReviewController.requestReview()
```
するだけ

開発環境では「送信」ボタンが押せなくなってるので、押した後のUXは確認できない

本番環境では・・・
★をつけたあとレビュー文言入力するか問われる。するを選んでもAppStoreに遷移せずアプリ内で入力できる。

# 使ってみたところ・・・

レビュー数が数年間合計で24だったアプリが、一晩で80ついた。

レビュー訴求呼び出したとき、３回表示されてないユーザだったら必ず表示されるようだ。

条件をゆるくしてしまうと３回までは出まくってしまうので、
条件を厳しくするか、WebAPIなどで外部から出現条件をコントロール出来たほうが良さそう。
iOS11 で UIScrollView の contentInsetがずれる問題 


既存のアプリをiOS11のシミュレータとかで動かすと結構な頻度で遭遇するかもしれません。

これは iOS11から scrollView で NavigationBar や ToolBar にあわせて contentInset を調整しなくてよくなったためです。
iOS10アプリでそのへんを考慮した調整をしていると、ずれます。
（UIScrollViewを内包してるWKWebView, UIWebView, UITableViewも同様）

※ 公開済みの資料をもとに書いてますが、問題ありましたら教えてください

# 資料

詳細　（要Safari）
https://developer.apple.com/videos/play/wwdc2017/204/
https://developer.apple.com/videos/play/wwdc2017/204/?time=1090
この辺から語られている

# どう変わったの

![image.png](https://qiita-image-store.s3.amazonaws.com/0/48695/e56f8dfc-3774-26b5-5148-b802ac3d6193.png)

今まではNavigationBarとかを設置していたらcontentInset.topを設定してやっていたが



![image.png](https://qiita-image-store.s3.amazonaws.com/0/48695/5b21fd2f-8fdd-088c-d4cd-779ef9aeda2b.png)

iOS11からはUIKitが勝手に調整してくれます、ということだそうです

`adjustedContentInset.top` に調整された分の値が入ってます

※ToolBarなども同様

# 実装の話

https://developer.apple.com/documentation/uikit/uiscrollviewcontentinsetadjustmentbehavior

UIScrollViewに、

```swift
var contentInsetAdjustmentBehavior: UIScrollViewContentInsetAdjustmentBehavior
```

というプロパティが増える。
ここに上記enumをセットしてやることで勝手に調整してくれたりしてくれなかったりする。
 デフォルトが `automatic` で、勝手に調整することになっているため、
iOS10までのアプリでscrollViewのcontentInsetを自分で調整してるアプリは、そのままだとずれてしまう。

`never` を指定しつつ既存のcontentInset調整をそのまま活かすか、 
`automatic` のまま新しく調整しなおすかになるかと思われます
CentOSにnginxをインストールする方法

# 基本
nginxのリポジトリが登録済みの場合はインストール可能

```
# yum install -y nginx
```

# 問題点
nginxのリポジトリが登録されてない場合、`yum install nginx`コマンドの結果が`No package nginx available.`となりginxがインストールできない

```
# yum install -y nginx

Loaded plugins: fastestmirror
base                                                     | 3.6 kB     00:00
extras                                                   | 3.4 kB     00:00
updates                                                  | 3.4 kB     00:00
(1/4): base/7/x86_64/group_gz                              | 155 kB   00:00
(2/4): base/7/x86_64/primary_db                            | 5.6 MB   00:01
(3/4): updates/7/x86_64/primary_db                         | 7.8 MB   00:01
(4/4): extras/7/x86_64/primary_db                          | 191 kB   00:01
Determining fastest mirrors
 * base: ftp.iij.ad.jp
 * extras: ftp.iij.ad.jp
 * updates: ftp.iij.ad.jp
No package nginx available.
Error: Nothing to do
```

# 解決方法
リポジトリを追加してから`yum install　nginx`コマンドを実行する

```
# vi /etc/yum.repos.d/nginx.repo
```

```/etc/yum.repos.d/nginx.repo
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=0
enabled=1
```

```
# yum install -y nginx
```
Slackでファイルアップロードを禁止させるためには？

# 概要

　社内のセキュリティポリシーでモバイルのSlack APPからのファイルDLを禁止するようにと、ク〇なルールがあったのでいろいろと調べた結果を共有します
　同様な要件を要求されている方がいれば参考までにご活用ください

　そもそもこのルールはモバイルを紛失した際にデータの流出を考慮したものだそうです...
　また、なにかご知恵があればご教授くださいー

# 結論

想定内ですが、
***モバイルAPPからのDL禁止する機能はないOrz***

ダメ元でSlack本部にこのような機能追加は可能かと問い合わせたところ以下の返信がありました（想定内ｗ）

```
Hi there,

Thanks for reaching out. I'm afraid it's not possible to restrict file uploads/downloads in Slack and there isn't a way to add this functionality to Slack unfortunately. It's not a functionality our product team are considering adding in the future either. I'm sorry I don't have better news for you on this one today. If you have any further questions please do let me know.

All the best,
```

# 妥協案

## ファイルアップロードさせないようにする

- ファイルのやり取りはURLリンクで行う（運用ルールベースだと大変）  
  ファイルの実態は別の認証機構が必要なサービスにする
- BOTでファイルアップロードしたら即削除するように監視する（Snippetは残したい）
  残念ながらSnippetとアップロードしたファイルの区別ができない
  - 「xxxxx.js」、「xxxxxx.txt」、「xxxxx.py」などの拡張子がつくファイルをアップロードした場合は、Snippetとして認識される
  - 「xxxxx.xls」、「xxxxx.jpg」などはアップロードしたファイルとして区別できる
  - カッコ悪いが[file object](https://api.slack.com/types/file)のtitleに拡張子が入っている場合は、添付ファイルとして見なす  
    ※ファイルアップロード時に拡張子を含むファイル名が自動的にtitleになる  
    [botkit](https://github.com/howdyai/botkit)での削除サンプルソース

    ```javascript:botkit-slack

    // file 作成時のイベント
    controller.on('file_public', function(bot, file) {
        const fileId = file.file_id;
        bot.api.files.delete({
                file: fileId
            }, function(err, res) {
                if (err) {
                    console.error(err);
                } else {
                    console.log(res);
                }
          });
    });
    ```
  - プライベートチャンネルのファイルアップロードイベントをトリガーできない  
    [files.list](https://api.slack.com/methods/files.list)でプライベートチャンネルにアップロードしたファイル、Snippetを取得できるので、取得したファイルIDをもとにファイル削除する  
    参考：http://lyncs.hateblo.jp/entry/2017/06/04/191421
  - Direct Messageでのファイルやメッセージはすべて取得できない（直接BOTとのやり取りは除く）

## 一日だけファイルアップロードを許可してもらう
　[メッセージとファイルの保存期間を設定する](https://get.slack.help/hc/ja/articles/203457187-Setting-up-custom-message-and-file-retention)機能を活用（有料アカウントのみ）する
  例えばアップロードしたファイルの保存期間を1日にすることで、最低限1日だけの猶予をもらうように交渉する（その間にモバイルの紛失しなければｗ）
webpackの設定をdevとproductionで分ける一例

webpackの設定を開発用と本番用で分けたいことがある。
例えば、SourceMapの有無とか種類を分けたい時や、uglifyするかしないかを切り替えたりなどが考えられる。

基本的には、[webpackのproductionのドキュメント](https://webpack.js.org/guides/production/)を見ればやり方は書いてあるが、やり方が幾つかあるので、自分のメモがてらその一例をここに書く。

## webpackのバージョン
- webpack: 3.4.1
- webpack-dev-server: 2.6.1

## 要件
### 開発用
- webpack-dev-serverでserveする
- SourceMapを付ける
- uglifyしない

### 本番用
- bundle.jsをビルドする
- SourceMapを付けない
- uglifyする

webpackとしては[productionでSourceMap使うと便利だよ](https://webpack.js.org/guides/production/#source-maps)と言っているが、まぁそれはそれとして、こういう要件だったとする。

## 方針
webpack.config.jsは１つだけで環境変数で処理を分岐する。
設定の差分が大きい場合は[configをmergeする方法](https://webpack.js.org/guides/production/#advanced-approach)を使うのがスッキリしそうだが、今回は大して差分はないので１つのconfigで済むようにした。

## 実装
### package.json
- webpack:devで開発用のwebpack-dev-serverを起動
- webpack:prodで本番用のbundle.jsをビルド
- webpack:prodには[引数で-pを渡してuglifyする](https://webpack.js.org/guides/production/#the-automatic-way)
- webpack:prodにはNODE_ENV=productionで環境変数を渡す  
  - -pを渡してもビルドスクリプト内ではNODE_ENVは設定されない（[Node Environment Variable
の青い部分に記載](https://webpack.js.org/guides/production/#node-environment-variable)）
  - お好みでcross-envを使っても良い

```json
{
    "name": "webpack-dev-prod",
    "version": "1.0.0",
    "scripts": {
        "webpack:dev": "webpack-dev-server",
        "webpack:prod": "NODE_ENV=production webpack -p"
    },
    "devDependencies": {
        "webpack": "^3.4.1",
        "webpack-dev-server": "^2.6.1"
    }
}
```

### webpack.config.js
- NODE_ENVで処理を分岐してSourceMapを設定する

```js
const path = require("path");

module.exports = {
    entry: {
        index: ["./src/test.js"]
    },
    output: {
        path: path.resolve(__dirname, "build"),
        filename: "bundle.js"
    }
};

if (process.env.NODE_ENV !== 'production') {
    module.exports.devtool = 'inline-source-map';
}
```

## 動作確認用コード
https://github.com/mwatanabe/webpack-dev-prod
趣味でwebサービスを公開するにはどんなサーバーが良いか？（ruby,rails,mySQL）

# この記事の目的

railsでちょっとしたサービスを公開したい時などに適した

* 安い
* 簡単
* 手間がかからない

上記の条件を満たしたサーバを探してみた。

# サーバーの種類

## Paas

PaaSとはPlatform as a Serviceの略でインフラ周りの設定を任せっきりにしてコードを上げるだけでサービスを公開できるものです。代表的なのが下記２つになります。

* [heroku](https://www.heroku.com/)
* [Sqale](http://sqale.jp/)→サービス終了（泣）

## Iaas

IaasとはInfrastructure as a Serviceの略。インフラ部分をカスタマイズできるサービスでAWSなどが当てはまる。また、利用する構成を途中で簡単に変更できるので、サービスの成長や、一時的なキャンペーンへの負荷対応などにも予め備えることが可能です。


## VPS

VPSはVirtual Private Serverの略。サーバを一部ではあるがまるごとかしてくれるものでOSなどかなり自由にカスタマイズできる。しかし、インフラの知識が必要なのでかなり上級者向け。
Macを使ってWIndows PCにLinuxを入れたときの備忘録

Windows 7 Professionalでシステム言語の変更が面倒くさかったので、Ubuntu Mateをインスコした時の備忘録。

# 準備
- USBメモリー(8.0 GB)
- Mac
- Windows PC

# USBメモリーのフォーマット
USBをシリアルポートに挿して、Disk Utility Appを使用してフォーマットする

- Disk Utility App
  - Format: MS-DOS(FAT)
  - Schema: Master Boot Recode

# ISOファイルをDL
- 次のURLから、CPUのアーキテクチャに合わせたISOファイルをDLする
- 今回はubuntu-mate-16.04.3-desktop-i386.isoをDLした

# ISOファイルをIMGファイルへ変換
- ターミナルから次のコマンドでファイルの変換を行なう

```console
$ hdiutil convert -format UDRW -o ./mate.img ./ubuntu-mate-16.04.3-desktop-i386.iso
Reading Master Boot Record (MBR : 0)…
Reading Ubuntu-MATE 16.04.3 LTS i386     (Apple_ISO : 1)…
Reading  (Windows_NTFS_Hidden : 2)…
.............................................................................................
Elapsed Time:  6.058s
Speed: 273.6Mbytes/sec
Savings: 0.0%
created: /Users/os10/Desktop/mate.img.dmg
$ # 処理が終わるとmate.img.dmgというファイルが作成される
```

# ファイルの拡張子の変更
余計なdmg拡張子が付いているため

```console
$ mv ./mate.img.dmg ./mate.img
```

# USBメモリーにUbuntu Mateをインストール

1.&nbsp;デフォルトのデバイスの確認

```console
$ # USBメモリを抜いて、次のコマンドを打つ
$ diskutil list
/dev/disk0 (internal, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                        *500.3 GB   disk0
   1:                        EFI EFI                     209.7 MB   disk0s1
   2:          Apple_CoreStorage Macintosh HD            499.4 GB   disk0s2
   3:                 Apple_Boot Recovery HD             650.0 MB   disk0s3
...
```

2.&nbsp;USBメモリのデバイスノードを確認

```console
$ # USBメモリを挿して、次のコマンドを打つ
$ # 増分のdev/Diskが対象のデバイスのノード
$ diskutil list
...
/dev/disk6 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *16.1 GB    disk6
   1:                 DOS_FAT_32 U                       16.1 GB    disk6s1
```

3.&nbsp;USBメモリのデバイスをアンマウント

```console
$ # 次のコマンドを打つ
$ diskutil unmountDisk /dev/disk6
Unmount of all volumes on disk6 was successful
```


5.&nbsp;USBメモリにインスコ

```console
$ # 次のコマンドは多少時間がかかる
$ sudo dd if=./mate.img of=/dev/disk6 bs=1m
1587+0 records in
1587+0 records out
1664090112 bytes transferred in 460.070103 secs (3617036 bytes/sec)
sudo dd if=./mate.img of=/dev/disk6 bs=1m  0.01s user 9.01s system 1% cpu 7:40.24 total
```

6.&nbsp;USBメモリの取り出し

```console
$ diskutil eject /dev/disk6
Disk /dev/disk6 ejected
```

# WindowsにLinuxのインスコ
- BIOSでUSBから起動の優先度をあげる
- Ubuntu Mateをインストールする


# 参考文献
http://tacatakatca.hatenablog.com/entry/20140202/1391322723
http://qiita.com/kpkpkp/items/6664a1dba97198b984ec
CentOS 7.3 に MariaDB 10 を入れてみる

#はじめに
業務でMariaDB使用する事になったが、全く使ったことがないため
下記VM環境にインストールして色々と触れる環境を構築。

| ソフトウェア | バージョン   |
|:------------|--------------:|
| VirtualBox  | 5.1.14        |
| Cent OS     | 7.3.1611      |
| Maria DB    | 10.1.11       |

尚、セキュリティ的な問題なのか外部に接続できず、
yumを使っての一発インストールができなかったので、
ソースを使って基本オフラインでインストールを実施。

#CentOSのインストール
以下URLを参照。

　【初心者でもわかる】Linux CentOSのインストール方法まとめ
　https://eng-entrance.com/linux-centos-install

自分が作業時は上記で特に問題なくインストール完了。

#MariaDBのインストール
以下URLを参照。

　MariaDB　はじめてのMariaDB　【第２回 CentOSにインストールしてみよう (前編)】
　http://www.sakc.jp/blog/archives/37172
　MariaDB　はじめてのMariaDB　【第３回 CENTOSにインストールしてみよう (後編)】
　http://www.sakc.jp/blog/archives/37541

丁寧に手順を書いてあるので基本的にはこのサイトの手順で問題無し。
と言うかこれ無しではインストールできなかった･･･。

ただ、初っ端のパッケージのインストールはyumが使えないのと
cmakeの実施時は行末が「.」だとそのまま実行されてしまうので、
環境の状況に合わせて若干変更が発生。

#変更点

上述の通り、パッケージのインストールについては
yumが使えないので、インストールディスクをマウントして
rpmで個別にインストールを実施してみる
(依存性の関係でサイトに記載以外のパッケージも含む)。

※パッケージはOSのバージョンで用意されているファイルが異なるはずなので
　lsコマンド等で確認してから実施する必要がある

```パッケージのインストール
# mount /dev/cdrom /media/CentOS
# cd /media/CentOS/Packages
# rpm -ivh gcc-4.8.5-11.el7.x86_64.rpm
# rpm -ivh gcc-c++-4.8.5-11.el7.x86_64.rpm
# rpm -ivh make-3.82-23.el7.x86_64.rpm
# rpm -ivh cmake-2.8.12.2-2.el7.x86_64.rpm
# rpm -ivh ncurses-devel-5.9-13.20130511.el7.x86_64.rpm
# rpm -ivh bison-2.7-4.el7.x86_64.rpm
# rpm -ivh xz-devel-5.2.2-1.el7.x86_64.rpm
# rpm -ivh zlib-devel-1.2.7-17.el7.x86_64.rpm
# rpm -ivh libxml2-devel-2.9.1-6.el7_2.3.x86_64.rpm
# rpm -ivh pcre-devel-8.32-15.el7_2.1.x86_64.rpm
# rpm -ivh keyutils-libs-devel-1.5.8-3.el7.x86_64.rpm
# rpm -ivh libcom_err-devel-1.42.9-9.el7.x86_64.rpm
# rpm -ivh libselinux-devel-2.5-6.el7.x86_64.rpm
# rpm -ivh libsepol-devel-2.5-6.el7.x86_64.rpm
# rpm -ivh pkgconfig-0.27.1-4.el7.x86_64.rpm
# rpm -ivh libselinux-devel-2.5-6.el7.x86_64.rpm
# rpm -ivh libverto-devel-0.2.5-4.el7.x86_64.rpm
# rpm -ivh krb5-devel-1.14.1-26.el7.x86_64.rpm
# rpm -ivh openssl-devel-1.0.1e-60.el7.x86_64.rpm
```

cmake実施時は「cmake .」になっていたが、
それだとパラメータを指定せずに実行されるっぽいので、
バックスラッシュに変更して実施。
これは自分の環境だけの問題なんだろうか？？？

```cmakeの実行
#cmake \
 -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
 -DMYSQL_DATADIR=/var/lib/mysql \
 -DMYSQL_UNIX_ADDR=/var/run/mysqld/mysqld.sock \
 -DENABLED_LOCAL_INFILE=1 \
 -DDEFAULT_CHARSET=utf8 \
 -DDEFAULT_COLLATION=utf8_general_ci \ 
 -DWITH_EXTRA_CHARSETS=all \
 -DWITH_INNOBASE_STORAGE_ENGINE=1 \
 -DPLUGIN_TOKUDB=NO 
```

と、ここまで書いてからISOからもリポジトリを作れば外部と接続できなくてもyumできるっぽい情報を見つけてしまった･･･自分の知見の狭さと浅さが露骨に分かって嫌になるなぁ･･･。
【質問】Swiftの配列、オプショナル型、Forループに関する質問です。（初心者）

【質問】

Swiftの配列、オプショナル型、Forループに関する質問です。


nilを含む配列の中にnil、数字がそれぞれ何個ずつあり、また数字の総計はどのくらいになるのかを表示するという問題に取り組んでいます。

配列の要素の中にnilが何個あり、数字が何個あるかを数えてprintで表示するまでは問題なくできました。しかし、配列内の数字の総和を求めようと、①、②を書き加えると、error: value of optional type 'Double?' not unwrapped; did you mean to use '!' or '?'?というエラーが発生してしまいました。

Forループの中でelseの条件にまで辿り着いたindexは数値として扱われていると思い、そのままsumOfexampleArrayに足せると思ったのですが、できません。

どうしてでしょうか。



var exampleArray: [Double?] = [154.4, nil, 133, 13.4, 221.3, nil, nil, 103.2]

var nilCounter :Int = 0
var numberCounter :Int = 0
var sumOfexampleArray :Double = 0 ...①

for index in exampleArray {
   　 if index == nil {
        　nilCounter += 1
    　} else {
       　 numberCounter += 1
        　sumOfexampleArray += index　...②
        
   　 }
        
    }


print("exampleArrayは\(nilCounter)個のnilを持っています。")
print("exampleArrayは\(numberCounter)個のnilを持っています。")
print("exampleArrayの数値の総和は\(sumOfexampleArray)です。")
DockerFileの主要な命令


|命令|説明| 
|:-----------|:------------|
|FROM|作成元のコンテナーイメージを[リポジトリ:タグ名]で指定|
|MAINTAINER|コンテナーイメージ作成者の名前を記載|
|ENV|コマンド実行時の環境変数を設定|
|RUN|指定のコマンドを実行|
|ADD|イメージ内にファイルを追加|
|EXPOSE|コンテナー内のアプリケーションが使用するポート番号を登録|
|CMD|コンテナー起動時に実行するコマンドを指定|
ESXi6.0 cron設定後の反映 再起動

#1 ESXi 5.1 および ESXi 5.5 の場合 →公式では記載されているが6.0も同じ
/bin/kill $(cat /var/run/crond.pid)
/usr/lib/vmware/busybox/bin/busybox crond

参考URL
https://orebibou.com/2015/01/vmware-esxi%E3%81%A7%E3%82%B3%E3%83%9E%E3%83%B3%E3%83%89%E3%82%84%E3%82%B9%E3%82%AF%E3%83%AA%E3%83%97%E3%83%88%E3%82%92%E5%AE%9A%E6%9C%9F%E5%AE%9F%E8%A1%8C%E3%81%95%E3%81%9B%E3%82%8B%E6%96%B9%E6%B3%95/

https://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=2094333
Screen Recordingの録画開始・停止を取得する

iOS11で追加されるScreen Recordingを使うと映像コンテンツを録画することができてしまいます。リリースしたアプリの中に録画されるとマズいアプリがあったので、対応方法を探していたのですが、iOS11 beta4から対応できることになったので紹介します。
# 環境
Xcode9 beta 4
iOS11 beta 4

# コード
```swift
override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    let screen = UIScreen.main
    screen.addObserver(self, forKeyPath: "captured", options: [.new, .old], context: nil)
}

override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
    guard let kp = keyPath else { return }
        
    if kp == "captured" {
        guard let ch = change else { return }
        
        let new = ch[NSKeyValueChangeKey.newKey] as! Bool
        let old = ch[NSKeyValueChangeKey.oldKey] as! Bool
        
        if new && !old {
            //録画開始
        } else if !new && old {
            //録画終了
        }
    }
}
```

# 参考サイト
[developer forum](https://forums.developer.apple.com/message/244430#244430)
jqで整形したJSONの結果をリダイレクトする、ファイルに保存する

# jqで整形したJSONの結果をリダイレクトする、保存する

jqはフィルタ(何を出力するか)を指定しないといけないとのことです。
`'.'`というフィルタを指定することで次のコマンドにパイプできるようです。

`'.'`はルート（一番外側の`{}`)を意味しているとのことです



```json:例
{
  "foo" : "FOO",
  "bar" : { 
    "baz" : "BAZ" 
  }
}
```

```shell-session:jq-sample
$ echo '{"foo" : "FOO", "bar" : { "baz" : "BAZ" }}' | jq ".foo"
"FOO"
$ echo '{"foo" : "FOO", "bar" : { "baz" : "BAZ" }}' | jq ".bar"
{
  "baz": "BAZ"
}
$ echo '{"foo" : "FOO", "bar" : { "baz" : "BAZ" }}' | jq ".bar.baz"
"BAZ"
$ echo '{"foo" : "FOO", "bar" : { "baz" : "BAZ" }}' | jq "."
{
  "foo": "FOO",
  "bar": {
    "baz": "BAZ"
  }
}
```


### リダイレクトする

```shell-session
$ cat before.json | jq '.' | grep -e "foo" 
```

### ファイルに保存する

```shell-session
$ cat before.json | jq '.' > after.json 
```

---
https://stackoverflow.com/questions/33247228/how-to-use-jq-in-a-shell-pipeline
http://qiita.com/takeshinoda@github/items/2dec7a72930ec1f658af
JSでクラスっぽいことをする

# 1.はじめに

JSで使いやすいクラスの雛形があればいいなと思ったので試行錯誤してみます。
ES6まではクラスという概念はサポートされないので、あくまでクラスっぽく書くというのがポイントになります。
フレームワーク頼らず、フルスクラッチでクラスを作る時にJAVAや.NETみたいにキレイに分かりやすく書きましょう。

# 2.要件
1. PrivateとPublicの変数、メソッドをそれぞれ管理できる
2. 複数インスタンスをnewで作成可能にする
3. イベントハンドラを利用してデータ更新を検知して何かできるようにする

# 3.やってみよう！
```javascript:
// window.mylibという名前空間的なものを作って初期化
window.mylib = Object.create({});
//　　window.mylib以下にクラス的なものを作ります。
window.mylib.UserModule = function(svname) {
  //  自身のクラスをselfとして保持
  var _self = this;

  //  プライベート変数
  var _country = "Japan";

  //  パブリック変数
  _self.time = new Date();
  _self.service_name = svname;

  //  プライベートメソッド
  var formatName = function(number){
    return _self.service_name + "へようこそ(" + _country + ")" + number;
  };

  //  パブリックメソッド
  _self.getFormattedName = function(){
    return formatName(1);
  };
  _self.setCountry = function(country){
    _country = country;
  };
  _self.getCountry = function(){
    return _country;
  };

  //  イベントハンドラの登録
  _self.model = {"user_id": 1 , "name": "JIRO" , "address": "Ebisu", "service_name": undefined};
  _self.proxy = new Proxy(_self.model, {
    get: function(object, target, newval) {
      console.log('get handler is called');
      console.log(target);
      console.log(object);
      console.log(newval);
    },
    set: function(object, target, newval){
      console.log('set handler is called');
      console.log(object);
      console.log(target);
      console.log(newval);

      object[target] = newval;
      if(target == "service_name"){
        _self.service_name = newval;
      }
      console.log(_self.model);
    }
  });

  return _self;
};

```

### 1.window.mylibという名前空間的なものを作って初期化
> window.mylib = Object.create({});

### 2.window.mylib以下にクラス的なものを作る
> window.mylib.UserModule = function(svname) {

### 3.JSではthisの値がスコープによって変化してしまうので_selfにthisを予め入れておく
> var _self = this;

### 4.パブリック変数とメソッド
> _self.service_name = svname;
> _self.getFormattedName = function(){

### 5.プライベート変数とメソッド
> var _country = "Japan";
> var formatName = function(number){

### 6.イベントハンドラ
[Proxy](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy)を使ってイベントハンドラを設定
>_self.proxy = new Proxy(_self.model, {...});


# 4.実行結果を確認してみる
### インスタンス1作成

```javascript
var um1 = new window.mylib.UserModule("楽天");
um1.getFormattedName();
>"楽天へようこそ(Japan)1"
```

### インスタンス2作成

```javascript
var um2 = new window.mylib.UserModule("アマゾン");
um2.getFormattedName();
>"アマゾンへようこそ(Japan)1"
```

### private変数の値が変わるか確認
```javascript
um1.setCountry("England");
um2.setCountry("Israel");

um1.getCountry();
>"England"
um2.getCountry();
>"Israel"
```

### public変数の値が変わるか確認
```javascript
um1.service_name = "メルカリ";
um2.service_name = "ヤフー";

um1.getFormattedName();
>"メルカリへようこそ(England)1"
um2.getFormattedName();
>"ヤフーへようこそ(Israel)1"
```

### プロキシ経由でのアクセスをしてイベントハンドラが正常に動くか確認
```javascript
um1.proxy.service_name = "通販さいと";
>set handler is called
>Object {user_id: 1, name: "JIRO", address: "Ebisu", service_name: undefined}
>service_name
>通販さいと
>Object {user_id: 1, name: "JIRO", address: "Ebisu", service_name: "通販さいと"}

um1.getFormattedName();
>"通販さいとへようこそ(England)1"
```