OmniAICreator/Qiita-1.07M huggingface dataset:
[さくらVPS]CentOS7にphp7 + php-fpm + nginxをインストールする

#はじめに
さくらVPSを新しく借りたのでphp7 + php-fpm + nginxの環境をつくる

# 環境
OS: CentOS Linux release 7.4
WebServer: nginx 1.13.9
DocumentRoot: /var/www/html
Domain: www.example.com

# まず
```
# yum update
```
## EPELリポジトリの追加
```
# yum -y install epel-release
```

yum コマンド実行時は自動的にEPELリポジトリが使用されるようになる。
--enablerepo=repo名を指定した時のみ使用するようにしたい場合は
以下を編集する。

```/etc/yum.repos.d/epel.repo
[epel]
enabled=1
↓ 変更
enabled=0
```

# remiリポジトリの追加
```
# rpm -Uvh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm
```

yum コマンド実行時は自動的にEPELリポジトリが使用されるようになる。
--enablerepo=repo名を指定した時のみ使用するようにしたい場合は
以下を編集する。

```/etc/yum.repos.d/remi-safe.repo
[epel]
enabled=1
↓ 変更
enabled=0
```

# Nginx
## /etc/yum.repos.d/nginx.repoを作成

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

## Install

```
# yum -y --enablerepo=nginx install nginx
# nginx -v 
nginx version nginx/1.13.9
```
## 起動設定
```
# systemctl start nginx
# systemctl enable nginx
# systemctl status nginx
```
## 設定ファイルの編集

###初期設定ファイルのバックアップをとる

```
cd /etc/nginx
# cp nginx.conf nginx.conf.org
cd /etc/nginx/conf.d
# cp default.conf default.conf.org
```

###設定ファイルを編集

```/etc/nginx/conf.d/default.conf
server {
    listen       80;
    server_name  localhost;
    root   /var/www/html;
    charset UTF-8;
    access_log  /var/log/nginx/www.example.com.access.log  main;
    error_log  /var/log/nginx/www.example.com.error.log;

    location / {
        index index.php index.html index.htm;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

}

```

### 再起動

```
# systemctl restart nginx
```

# php, php-fpm 
## Install

```
# yum -y install --enablerepo=epel,remi,remi-php72  php php-mbstring php-pdo php-mysqlnd php-fpm php-gd
php -v
PHP 7.2.3
```
最初にインストールした際に下記エラーが発生したので--enablerpoにepelリポジトリを追加。

```
エラー: パッケージ: php-7.2.1-1.el7.remi.x86_64 (remi-php72)
要求: libargon2.so.0()(64bit)
```

## 初期設定ファイルのバックアップをとる

```
cd /etc/php-fpm.d
cp www.conf www.conf.org
```

## 設定ファイルを編集

```/etc/php-fpm.d/www.conf
- user 
+ user nginx
- group
+ group nginx
- listen = 127.0.0.1:9000
+ /var/run/php-fpm/php-fpm.sock
- ;listen.owner = nobody
+ listen.owner = nginx
- ;listen.group = nobody 
+ listen.owner = nginx
```

## php-fpmを再起動

```
# systemctl restart php-fpm
```

# 確認
## とりあえずphpinfoを表示させる

```/var/www/html/index.php
<?php phpinfo(); ?>
```
ブラウザでhttp://Domain名
でアクセスしてphpinfoが表示されればOK

# 参考
[CentOS7+nginx+php7+MariaDBの環境構築](https://qiita.com/you0328/items/cdc92e3fde2dc3bc1d51)
[sanosoft@ウィキ PHP7.2のインストール](https://www40.atwiki.jp/sanosoft/pages/74.html)
FileManagerまとめ

# パスの取得
# Documents
``` swift
let path = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let documentsPath = NSHomeDirectory() + "/Documents"
```
# Library
``` swift
let path = NSSearchPathForDirectoriesInDomains(.LibraryDirectory, .UserDomainMask, true)[0]
let libraryPath = NSHomeDirectory() + "/Library"
```

# Application Support
``` swift
let path = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true)[0]
let applicationSupportPath = NSHomeDirectory() + "/Library/Application Support"
```

## Caches
``` ObjC
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *path = [paths objectAtIndex:0];
```

``` swift
let path = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0]
let cachesPath = NSHomeDirectory() + "/Library/Caches"
```

## tmp
``` ObjC
NSString *path = NSTemporaryDirectory();
```

``` swift
let path = NSTemporaryDirectory()
```


iOS /tmpと/Cachesディレクトリの違いと運用方法 - Qiita
https://qiita.com/yusuga/items/8c057a67e0ac021c54bc
iOSアプリのファイル保存について - Qiita
https://qiita.com/nnsnodnb/items/13642c4a8d55641f893e

# パスの連結
``` ObjC
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"hello.txt"];
NSLog(@"filePath=%@", filePath);
```

# 存在
``` ObjC
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"NewDir"];

if (![[NSFileManager defaultManager] fileExistsAtPath:dirPath]) {
    NSLog(@"file don't exist.");
}
```

# フォルダの作成

``` ObjC
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *dirPath = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"NewDir"];

NSError *error = nil;
if(![[NSFileManager defaultManager] createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error]) {
    NSLog(@"Error occurred when directory was making! [%@]", [error localizedDescription]);
}
```

# 移動
``` ObjC
[[NSFileManager defaultManager] moveItemAtPath:filePath toPath:afterPath error: &error];
```

# コピー
``` ObjC
[[NSFileManager defaultManager] copyItemAtPath:filePath toPath:afterPath error: &error];
```

# 削除
``` ObjC
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
```

## 内容の取得
``` ObjC
NSError *error = nil;
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"hello" ofType:@"txt"];
NSString *document = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:&error];
NSLog(@"document=%@", document);
```
jQueryからsubmitするとHTML5 requiredが効かなくなる

回避策を探してもいい感じに検索できなかったので、メモ
イケていないので、もっと良い回避方法をご存知の方はコメントしていただけると幸いです

# 事象
タイトルの通り

## 詳細
HTML5の`required`簡単なバリデーションならしてくれる。うれしい。
ただ噂ではSafariでは言うこと聞いてくれないらしいから注意。

[HTML <input> required Attribute](https://www.w3schools.com/tags/att_input_required.asp)
こんな感じで使う。
「`submit`される直前にチェックしてくれる」がポイント。

この`required`は困ったことに`jQuery`の`submit()`を使うと、バリデーションされずに`submit`されてしまう。
なんとかそれを回避したい。

# 解決方法

```html:ボタン
<input type="button" class="btn btn-primary" value="登録" name="regist" onclick="doPost();">
<input type="submit" value="不可視ボタン"  style="display:none" name=submitBtn>

```


```javascript:doPost()
function doPost(){

    // $('#form').submit(); <- これだとrequiredが効かない NG

    // HTMLのtype=submitのボタンをjsからクリック
    $("input[name=submitBtn]").click();
}
```

イケてなさすぎて笑われたので、使うときは要注意

### 参考

[jQueryのsubmitでrequiredが効かない](http://tk2-207-13211.vs.sakura.ne.jp/2016/04/822/)
[html5のrequiredはJSからsubmit()を呼んだ時には効かない。ので不可視のsubmitボタンを埋め込んどいてJSからクリックすることで発火させる必要あり。](http://b.hatena.ne.jp/entry/159885794/comment/stealthinu)
文字色をコードで変更する方法

#文字色をコードで変更する
## 経緯
　ある数値が指定の値になった場合のみボタンの文字色を変更して、
　かつそのボタンを非活性化にしたかったので、FormのようにEnabledをfalseにすれば
　ボタンが非活性化かつ色が変わると思っていましたが、ボタンには既にTriggerで押下時に
　色が変わるように設定してあったので、Enabledをfalseにしても非活性化になるだけで、
　ボタンの色も文字色も変化しませんでした。なので、調べる事になりました。
　尚、ここで記載するタグにはそのTriggerの記述を省き、ボタンの押下回数が2回目の時に、
　文字色を赤色に変更する記述にしています。
##タグ
    <Grid>
        <Button Name="BtnOK" HorizontalAlignment="Left" Margin="165,183,0,0" VerticalAlignment="Top" Width="75">
            <TextBlock x:Name="txt_Ok" Text="OK"/>
        </Button>
        <Button Name="BtnCancel" HorizontalAlignment="Left" Margin="289,183,0,0" VerticalAlignment="Top" Width="75" Click="BtnCancel_Click">
            <TextBlock x:Name="txt_Cancel" Text="キャンセル"/>
        </Button>
        <TextBlock x:Name="txtAnswer" HorizontalAlignment="Left" Margin="143,108,0,0" TextWrapping="Wrap" Text="0" VerticalAlignment="Top" Height="25" Width="126" FontSize="20"/>
        <Button Name="BtnPuls" HorizontalAlignment="Left" Margin="289,108,0,0" VerticalAlignment="Top" Width="75" Click="BtnPuls_Click">
            <TextBlock x:Name="txtPuls" Text="+" FontSize="25"/>
        </Button>

    </Grid>
##コード
        private void BtnPuls_Click(object sender, RoutedEventArgs e)
        {
            num++;
            txtAnswer.Text = num.ToString();
            if (num == 2)
            {
                BtnOK.Foreground = new SolidColorBrush(Colors.Red);
                BtnOK.IsEnabled = false;
            }
            else
            {
                BtnOK.Foreground = new SolidColorBrush(Colors.Black);
                BtnOK.IsEnabled = true;
            }
        }

        private void BtnCancel_Click(object sender, RoutedEventArgs e)
        {
            num = 0;
            txtAnswer.Text = num.ToString();
            BtnOK.IsEnabled = true;
            BtnOK.Foreground = new SolidColorBrush(Colors.Black);
        }

##結果
###1回目
　![image.png](https://qiita-image-store.s3.amazonaws.com/0/230574/4fdbd5ee-f6f8-2f4f-8167-f7b7b4f45870.png)
###2回目
![image.png](https://qiita-image-store.s3.amazonaws.com/0/230574/cc2bf2e7-c69c-958f-809d-87cb52c24fae.png)
###3回目
![image.png](https://qiita-image-store.s3.amazonaws.com/0/230574/f39e53e7-45af-3614-3d2b-666441ed959b.png)
Fatal error: Call of deleted method が出たら carthage update と Clean Build Folder で出なくなった

呪いの言葉 `Fatal error: Call of deleted method` を網膜に焼き付けてしまった場合、自分は次の方法を行うことで解呪することができました。

原因特定が割り出しにくいので少しでも困っている人の光になればいいなと。

## 注意
- 原因は１つじゃないのでこの方法が全ての困っている人に有効ではありません。
- 順番は恐らく依存していないと思います。


## 試したこと

1. ライブラリアップデート
2. Clean Build Folter

## ライブラリアップデート

問題となっていたコードが Carthage で管理されたライブラリだったので、 carthage update で更新しました。

## Clean Build Folder

Clean Build Folder にして丸ごとクリーンしました。
Xcode の Clean を alt を押しながらカーソル合わせることで Clean が Clean Build Folder に変わります。
外国人が郵便局のe転居サービスを利用する場合のtips

# カタカナ名の人は郵便局の転居転送サービスを使えない？

外国人の名前を漢字欄と読み仮名欄で同じカタカナ表記にすると受け付けてくれないのです。電話で問い合わせても、どちらもカタカナだと受付できないので郵便局備え付けの紙で提出するように言われてしまいました。

## ローマ字表記できる場合にはe転居で登録する方法があった！
漢字欄にアルファベット（全角）、読み仮名欄をカタカナ（全角）にしたら通りました。
でも、日本人で名前がカタカナの人はこの方法が使えないですね。
関数、where句に書くか トップレベルに書くか（Haskell）

# 概要
　下記のようにsugar以外がswordを参照していない場合は、
swordをトップレベルに定義するか、where句に定義するかが選べるかと思います。

```haskell
sugar :: Int -> Char
sugar = chr . sword

sword :: Bool -> Int
sword True  = 1
sword False = 0
```

or

```haskell
sugar :: Int -> Char
sugar = chr . sword
  where
    sword :: Bool -> Int
    sword True  = 1
    sword False = 0
```

どっちのが好き？

# 前置き
## let/where句の書き分け

　僕の以下のようにlet/where句を書き分けています。

- where
    - 本体への変数を参照せずに、独立したスコープを持つもの
- let
    - 本体への変数を参照しているもの

まあごくたまに崩してる気がしますが！ :joy:

### ここでは正しくない例

```haskell
foo :: Int -> Int
foo x =
  let f :: Int -> Int
      f = (+10)
  in f y
  where
    y = x + 1
```

　この`f`程度ならいいものの、ときどき
「なんで関数本体（let句）に含んだ？ なんで関数本体を肥大化させた？」
と思うものがあります。

　この`y`程度ならいいものの、ときどき
「コードを上から下に見る人の気持ちを考えたことある？ ねえどんな気持ちでwhere句に書いたの？」
と思うものがあります。

### ここでは正しい例

```haskell
foo :: Int -> Int
foo x =
  let y = x + 1
  in f y
  where
    f :: Int -> Int
    f = (+10)
```

人間の思考法に優しい感じがする。

# 本題
　ghciでは、module句で公開していないけれどトップレベルに定義してあるというものは
`:load`コマンドで読み込めるらしいのです。  
（Thanks @igrep, @Mizunashi\_Mana)

　なので僕はデバッグ上での利便性を鑑みて、
ghciで読み込み可能にしておきたいものはトップレベルに、
特に読み込みたいと思うことはないだろうものはwhere句に定義することにしました。

　以下の例の`lambdaParser`と`applicationParser`が、
特にmodule外には出したくないけどghciの`:load`では読み込みたいものに当たります。  
（[hs-sonoda](https://github.com/aiya000/hs-sonoda)での実例の抜粋。
詳しくは[このcommit](https://github.com/aiya000/hs-sonoda/commit/9efd7a547ed89ce46ebb6cc2124385a716ccd15b)と
src/Sonoda/Parser.hsを参照のことお願いします）

```haskell
module Sonoda.Parser
  ( exprParser
  ) where

-- | A parser of expressions
exprParser :: CodeParsing m => m Expr
exprParser = ExprAtomic <$> atomicValParser
        <<|> lambdaParser
        <<|> ExprSyntax <$> syntaxParser
        <<|> P.parens exprParser
        <<|> applicationParser

-- | A parser for lambda abstractions
lambdaParser :: CodeParsing m => m Expr
lambdaParser = do
  P.symbolic '\\'
  n <- identifierParser
  P.colon
  t <- typeParser
  P.dot
  x <- exprParser
  pure $ ExprLambda n t x

-- | A parser for function applications
applicationParser :: CodeParsing m => m Expr
applicationParser = do
  applyerOrLonlyIdentifier <- terminatorParser
  maybeApplyee <- const Nothing <$> P.eof <|> Just <$> exprParser
  case maybeApplyee of
    Nothing      -> pure applyerOrLonlyIdentifier
    Just applyee -> pure $ ExprApply applyerOrLonlyIdentifier applyee
  where
    -- A parser for terms that is not an application
    terminatorParser :: CodeParsing m => m Expr
    terminatorParser = ExprAtomic <$> atomicValParser
                  <<|> lambdaParser
                  <<|> ExprSyntax <$> syntaxParser
                  <<|> ExprParens <$> P.parens exprParser
                  <<|> ExprIdent  <$> identifierParser
```
MacのFinderで不可視ファイルの表示・非表示を簡単に切り替える方法

# 不可視ファイルを表示する

不可視ファイルを表示にする設定

```bash
defaults write com.apple.finder AppleShowAllFiles TRUE
```

設定を反映させる

```bash
killall Finder
```

これだけでFinder上で不可視ファイルが表示されるようになる。

# 不可視ファイルを非表示に戻す

```bash
defaults write com.apple.finder AppleShowAllFiles FALSE
```

表示の時の```TRUE```が```FALSE```に変わるだけ
再度設定反映用のコマンドをたたけばOK
今回の音声合成アプリ開発に参考したサイト

今回ウェブサイトのアプリですが、スマホのセンサーを活用して、シェイク検出して動作するアプリ開発をしています。
その中で、音声合成を活用したかったので、ネット検索して情報を集めていました。
最新の記事がなく困りましたが、今回ご紹介する記事を参考にアプリを作ることができました。

私の備忘録の意味も込めて、ここにシェアします。

http://www.allinthemind.biz/markup/javascript/web_speech_api.html

http://www.antytle.com/media/topic/29

https://caniuse.com/#feat=speech-synthesis

http://docs.hatenablog.jp/entry/speech-synthesis

http://blog.e-riverstyle.com/2015/01/web-speech-apitts.html

この記事が、一番分かりやすいかな。
http://an.hatenablog.jp/entry/2016/10/15/121700
pyenvをちゃんと消してから入れ直す

## はじめに
Nortonのクリーンアップをしたものをそのままゴミ箱に捨てたところ証明書周りでエラーが出たのでpyenvを入れ直したのですが,アンインストールするだけでは治らなかったので書いておきます

## 環境
- macOS High Sierra 10.13.3
- バージョン管理は`pyenv-virtualenv`を使用

## メモ

- パスを変える必要はないので, パスの記述は消しません
- pythonごと消すのでバージョンを覚えておく必要があるならば事前に確認しておいてください

## 手順

### **pyenv関連のファイルを削除**
[こちら](https://qiita.com/SonoT/items/24f8a14555aea4961f9b)を参考にさせていただきました
Pyenvをuninstallするだけではちゃんと消えてくれないので周りのファイルもなるべく消します

```shell
$ which python  #=> /Users/xxx/.pyenv/shims/python みたいなパスが出ると思います
$ rm -rf /Users/xxx/.pyenv  # 上の操作で出てきたパスの.pyenvまでのパスを入力します
```

ここで`permission denied`が出て, 消せないファイルがでてくると思いますが結論からいうと僕の場合はこれ以上は何もしなくても大丈夫でした

### **pyenvのアンインストール**

```shell
$ brew uninstall pyenv-virtualenv  # virtualenvを使っている場合はこれを先にする
$ brew uninstall pyenv
$ brew list  # pyenv, virtualenvが消えていることを確認する
```

### **pyenvの再インストール**

```shell
$ brew install pyenv
$ brew install pyenv-virtualenv
```

### **pythonのインストール**

```shell
$ pyenv install --list  # 入れたいpythonのバージョンを確認する
$ pyenv install 3.6.1  # 例) python3.6.1をインストールする
```
webサイトを作る際に参考にした記事の備忘録①

#はじめに
　Webサイトを作る際に参考にしたリンク先をまとめた記事になります。
　はてなブログよりも、ブログ書くならQiitaで書いたほうがいいと勧められたので、こちらで書くことにしました。

　色々と行き詰まりを感じた時に調べたことをそのまま貼り付けています。

##１。まず、グーグルのウェブページ内にマップを組み込む方法。
[support.google.com](https://support.google.com/maps/answer/144361?co=GENIE.Platform%3DDesktop&hl=ja&oco=1)

 

##２。グーグルマップをウェブページ内に組み込み、かつ、カスタマイズをする方法。

[webkikaku.co.jp](https://webkikaku.co.jp/blog/webdesign/googlemap-customize/)

 

##３。スクロールを停止する方法。
ハンバーガーメニューを開いた時のみ、スクロールを停止させたかったんです。

[blog.mismithportfolio.com](https://blog.mismithportfolio.com/web/20150529scrollfixed)

実際に使用したCSSは、display: fixed; で済ませちゃいましたが。


##４。フレックスボックスを使った表示の揃え方。

[www.granfairs.com](https://www.granfairs.com/blog/staff/centering-by-css)


##５。ハンバーガーメニューの作り方

[saruwakakun.com](https://saruwakakun.com/html-css/reference/nav-drawer)

↓実際に参考に使ったのはこちら。

[web-seikatsu.hatenablog.jp](http://web-seikatsu.hatenablog.jp/entry/2017/10/07/213000)
 

##６。まだ実装しきれていないこれからするやつ。

[www.aiship.jp](http://www.aiship.jp/knowhow/archives/28419)
 

色々と備忘録をメモしていきたいですね。
"docker load"したら"no space left on device"となったときの対策

# 問題
```
docker load < image.tar
```
したら、"no space left on device"が返ってきた。
"df -h"してみると、なるほど、容量がいっぱいだ。
削除できるファイルもあんまりない。どうしよう。

# 対処法
```
/var/lib/docker
```
にあるdocker関連ファイルを、全部外付けHDDに移してしまい、/var/libにシンボリックリンクを貼る。

具体的なコードとしては、以下のような感じ。

```
sudo mv /var/lib/docker /mnt/hdd/docker
sudo ln -s /mnt/hdd/docker /var/lib/docker
```
"/mnt/hdd"ていうのは外付けHDDをマウントしたディレクトリ。

子供だましのようだが、これで無事にload→runまで成功した。
custom event

### dispatch eventと共に発行
```js
var _ev=new CustomEvent('eee');
 _ev.mes=count;//need the no reserve param 
 count++;
 el.dispatchEvent(_ev); 
```

### detailが標準だが、オブジェクトに追加しても転送される。予約語を避ける。
```js
 _ev.mes=count;//need the no reserve param 
```
### onceも使える。
```js
el.addEventListener('eee',function(ev){this.classList.toggle('red')},{once:true});
```

### 全部
```html
<input></input>
<button>b</button>
<style>
 body{background-color:#111;color:#eee}
.red{background-color:red}
</style>
```
```js
let el=document.querySelector('input')
,btn=document.querySelector('button')
el.addEventListener('eee',function(ev){this.classList.toggle('red')},{once:true});
el.addEventListener('eee',function(ev){this.value =ev.mes},false);
;
let count=0;
btn.onclick=function(ev){
var _ev=new CustomEvent('eee');
 _ev.mes=count;//need the no reserve param 
 count++;
 el.dispatchEvent(_ev);
}

```
### ショート
```js
 el.dispatchEvent(Object.assign(new CustomEvent('eee'),{mes:count}));
```

### 追記
```js
//dont work!
el.oneee=function(ev){console.log(ev)};
el.eee=function(ev){console.log(ev)};
```
### オリジナルeventの転送はevを丸ごとコピーするとread onlyに対する複写エラーが起きる為、必要な物のみにする。
```js
let f=function(ev){
 let o={},needs=['keyCode','ctrlKey','metaKey','shiftKey','altKey','code','which']
 ;
  needs.forEach(d=>{ o[d]=ev[d] })
  this.dispatchEvent(Object.assign(new CustomEvent('i'),o)); // Object.assign(new C..., ev); dont work!
}
document.body.addEventListener('keydown',f,false)
document.body.addEventListener('i',function(ev){ console.log(ev) },false)
```
複数セグメントに所属する端末間でのファイル共有ができない問題

とある端末からpingは通るが共有フォルダにアクセスできないという表題ママの
現象が起きていたその解決策。netコマンド様様。
なお、備考にも書いているが本対応は閉じた環境でのみ適用すること。
外につながっている場合はSMBv2,v3を適用する方法を各自で参照されたし。

##前提
以下の二つのセグメントが存在する。
　	セグメントA:[192.168.1.xx]
　	セグメントB:[192.168.10.xx]

以下の3つの端末が存在する
　	端末1:Windows10 セグメントA,B双方所属
　	端末2:Windows10 セグメントA,B双方所属
　	端末3:WindowsServer2003 セグメントAのみ所属
	
##現象
端末2-端末3間で共有フォルダが参照できない。
端末2と端末3の間のpingは通る。
端末1からは端末2，3共に共有フォルダを参照可能。
	
##原因
端末2において、ファイル共有に必要なSMB設定がされていなかった。

##調査手順

①端末2のCmdにて下記コマンドを実施した結果を確認
	コマンド　：net use \\192.168.1.xx
	エラー内容："安全ではないため、ファイル共有に接続できません。 
			 この共有には古いの SMB1 プロトコルが必要です。このバージョンのプロトコルは安全ではなく、システムが攻撃される可能性があります。
			 システムには SMB2 以降が必要です。 この問題を解決する方法の詳細については、https://go.microsoft.com/fwlink/?linkid=852747 を参照してください"
②適切なSMBを適用する手順を確認	
	
##対処内容
①コントロールパネル→プログラムの追加と削除→Windowsの機能の設定と復元から[SMB 1.0/CIFSファイル共有のサポート]のチェックを入れて再起動。
	
##備考
・端末2はデフォルトでwindows10ではなく、アップグレート版だったらしいがそれが原因?
・SMB1は非推奨となっているため、本体所は閉じた環境でのみの対処法。
AppServiceで、Always On (常時接続) と HttpsOnly は同時に動かない

# 要点

- 問題
  - 「常時接続」をONにしても、php-cgi.execが10分~20分ぐらいのアイドル状態を経ると消える
- 理由
  - 「HTTPSのみ」をONにしていたが、常時接続と同時に有効にすると常時接続が機能しなくなるため
      - 常時接続は5分ごとに`/`に対してPINGリクエストを行うが、これが常にHTTPに対して行われる。HTTPSのみにするとPINGリクエストに対して302レスポンスが応答として返されるようになり、結果常時接続の機能が失われる
- 回避策
    - Google Apps ScriptやAzure Functionなどで定期的にURLのトップページをリクエストする
- 参考URL
    - https://github.com/Azure/app-service-announcements/issues/78
    - https://feedback.azure.com/forums/169385-web-apps/suggestions/31939219-enable-always-on-feature-for-https-only-web-apps

# 以降、愚痴

- 常時接続を有効にしていたが、なぜかKuduでプロセス一覧を見るとphp-cgi.exeはいつも消えていた
- そういう状態でページにアクセスすると、明らかに遅い（表示まで数秒かかることもざらにある）
- ぶっちゃけそういうもんだと思っていた
- しかし一度調べ始めると、現状がおかしいことが判明
- [web.configを使った回避方法](https://stackoverflow.com/questions/44724430/azure-app-service-always-on-with-custom-domain-redirect-not-hitting-default-web)や[IIS Managerを使った回避方法](https://github.com/projectkudu/kudu/wiki/Xdt-transform-samples#redirect-http-traffic-to-https)をやってみたが、うまくいかず
- 常時接続 + HTTPSのみ + 認証/承認 という3つとも使っている構成だったので、より罠にはまったらしい
  - 認証/承認 を使うと、HTTPSのみをOFFにしてもHTTPSを強制的につかうっぽい
macbook El Capitan Wifi のパスワードが記憶されない場合の対処法




# 概要
macbook のユーザ名, IDを変更することになったが、
その際にキーチェーンのパーミッションあたりも
うまく設定できていなかったため、
キーチェーンを変更できず、
Wifi パスワードが保存されていなかった。


# 問題 (現象)
macbook にOS をインストールしたが、
ユーザ名, IDを変更することになった。

すると本来自動で接続されるはずの Wifi が自動で接続されない。

## 確認したこと:
* 通常通り、パスワードは保存するようにしてある
* ネットワーク設定には、SSID として追加されている
* キーチェーンには 追加されていない

## 試したこと:
* Keychain First Aid (El Capitan にはない 削除された)
* キーチェーンのデータリセット
* `~/Library/Keychains/` の中身を削除や一時移動
* 各種リセット (NVRAM, SMC)

でも改善しない


## 仮説:
本来キーチェーン に保存されるはずのパスワードが
パーミッションのため保存できていない

事実、キーチェーンにデータを追加や変更しようとすると、
UNIX[Operation not permitted]
のようになる。



# 解決策

ここの説明に従う。

* OSをリカバリーモードで起動し、terminal で以下コマンドを実行。
* 
`chflags norestricted /V*/*/L*/Keyc*/*`

* 再起動

https://discussions.apple.com/thread/7357200
vagrantでよく使うコマンド一覧とvagrant自動起動のためのバッチファイル

#Vagrantコマンド一覧

##起動
```
cd フォルダ名
$ vagrant up
```

##ssh接続
```
$ vagrant ssh
```

##再起動
```
$ vagrant reload
```

##シャットダウン
```
$ vagrant halt
```

##一覧確認と削除
```
$ vagrant box list
$ vagrant box remove リストに出たファイル名
```

##確認
```
$ vagrant status
```

##一時停止
```
$ vagrant suspend
```

##suspendから復帰
```
$ vagrant resume
```

#自動起動のためのバッチファイル
```
$ cd Vagrantのフォルダ名
$ vagrant up
```
vagrantが保存されているディレクトリに.bat を作って保存。
デスクトップにショートカットを作ってクリックすればすぐに起動。

#複製
```
$ cd Ubuntu64
$ vagrant package
```
いつもvagrant up しているフォルダへ移動して vagrant package で package.box と言うファイルができるから
それを配布する。
または package.box 以外の名前にする場合は

```
$ cd Ubuntu64 
$ vagrant package --output Ubuntu64Copy.box
```
例： vagrant package [vm名] --output [名前.box]
フォルダに移動していれば、[vm名]入れなくても 複製できる。

##複製したBoxをインストール
```
$ vagrant box add Ubuntu64Copy Ubuntu64Copy.box
```

##インストールしたBoxの確認
```
$ vagrant box list
```

##インストールしたBox初期化
```
$ vagrant init Ubuntu64Copy
```

##Vagrant起動
```
$ cd Ubuntu64Copy
$ vagrant up
```

/Ubuntu64Copy/Ubuntu64Copy.box の Ubuntu64Copy.box はここで削除して良い。
Django で　アプリケーションの追加

以下で作成したプロジェクトに２つ目のアプリケーションを追加します。
[Django で Hello World](https://qiita.com/ekzemplaro/items/ef63edfa93caaab4071e)

２つ目のアプリケーションは、app02 とします。

作業は、proj01 のフォルダー内で行います。

>アプリケーションの作成

```bash
python manage.py startapp app02
```

>app02/views.py を作成します。

```py:app02/views.py
from django.http import HttpResponse

def index(request):
    str_out = "*** app02 ***<p />"
    str_out += "こんにちは<p />"
    str_out += "Apr/02 PM 20:35<p />"
    return HttpResponse(str_out)
```

>app02/urls.py を作成します。

```py:app02/urls.py
from django.urls import path
from . import views

urlpatterns = [
    path('', views.index, name='index'),
]
```

>proj01/urls.py を編集します。

```py:proj01/urls.py
from django.contrib import admin
from django.urls import include
from django.urls import path

urlpatterns = [
    path('app02/', include('app02.urls')),
    path('', include('hello.urls')),
    path('admin/', admin.site.urls),
]
```

>開発サーバーを動かします。

```bash
python manage.py runserver
```

http://127.0.0.1:8000/app02/ にアクセスしてみます。
![django_apr0201.png](https://qiita-image-store.s3.amazonaws.com/0/179446/b3a64a21-ca3b-dd94-0603-fd0550e825f9.png)
springのUriComponentsBuilderでクエリパラメータをエンコード

## 環境
```xml
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.0.0.RELEASE</version>
	</parent>
```

## エンコードの指示
<code>encode</code>でエンコードを指示する。

```java
URI target = UriComponentsBuilder.newInstance()
        .scheme("http")
        .host("example.com")
        .queryParam("foo", "b&r")
        .build()
        .encode()
        .toUri();
System.out.println(target);// http://example.com?foo=b%26r
```

エンコード済みのURLで<code>fromUri</code>を使う場合は<code>build(boolean encoded)</code>に<code>true</code>を指定する。

```java
URI source = new URI("http://example.com?foo=b%26r");
URI target = UriComponentsBuilder
        .fromUri(source)
        .build(true)
        .toUri();
System.out.println(target);// http://example.com?foo=b%26r

```

## ハマった点
もし<code>encode</code>を指定しない場合、エンコードは行われない。

```java
URI target = UriComponentsBuilder.newInstance()
        .scheme("http")
        .host("example.com")
        .queryParam("foo", "b&r")
        .build()
        .toUri();
System.out.println(target); // http://example.com?foo=b&r
```

もし<code>fromUri</code>でエンコード済みのURLを渡し、かつ、<code>build(boolean encoded)</code>に<code>true</code>を指定しない場合、エンコードが行われる。よって、結果的に<b>二重にエンコード</b>が行われる。

```java
URI source = new URI("http://example.com?foo=b%26r");
URI target = UriComponentsBuilder
        .fromUri(source)
        .build()
        .toUri();
System.out.println(target);// http://example.com?foo=b%2526r
```

## 参考
[[SPR-14256] Doc: UriComponentsBuilder does not encode query parameters - Spring JIRA](https://jira.spring.io/browse/SPR-14256)
Spring Data JPAで共通Repository作成

すべてのRepositoryに共通処理を定義したい場合の方法

# 実装方法
公式ドキュメントをそのままコピペしただけ

## 共通Repository実装
```java:MyRepositoryImpl.java
class MyRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> {
```

## 共通Repository設定
```java:JavaConfig.java
@Configuration
@EnableJpaRepositories(repositoryBaseClass = MyRepositoryImpl.class)
class ApplicationConfiguration { … }
```
or

```xml:config.xml
<repositories base-package="com.acme.repository" base-class="….MyRepositoryImpl" />
```

##参考
公式ドキュメント
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.customize-base-repository

terasolunaドキュメント
http://terasolunaorg.github.io/guideline/5.3.1.RELEASE/ja/ArchitectureInDetail/DataAccessDetail/DataAccessJpa.html#custommethod-all-label



# base-classを２つ以上定義したい場合
```xml:config.xml
<repositories base-package="com.acme.repository1" base-class="….MyRepository1Impl" />
<repositories base-package="com.acme.repository2" base-class="….MyRepository2Impl" />
```

https://stackoverflow.com/questions/15008809/multiple-jparepositories-in-xml-config-how-to-configure-with-enablejpareposit
Socket.io デバッグ情報の消し方

### デバッグ情報の消し方
console.logで出力した際にデバッグ情報がうざい時

```sample.js
// 定義
var app = require('http').createServer(handler),
    io = require('socket.io').listen(app);
// 対策
io.set('log level', 1);
```
これでデバッグ情報が表示されなくなる。
[WordPress][Nginx] プラグイン SiteGuard のログインURL変更機能を Nginx で使う

SiteGuardってプラグインのログインURL変更機能を使うと、`.htaccess` に以下の設定が追加されます。
`login-xxxx` はプラグインの設定画面で設定したログイン用のURL。

```
#SITEGUARD_PLUGIN_SETTINGS_START
#==== SITEGUARD_RENAME_LOGIN_SETTINGS_START
<IfModule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    RewriteRule ^wp-signup\.php 404-siteguard [L]
    RewriteRule ^wp-activate\.php 404-siteguard [L]
    RewriteRule ^login-xxxx(.*)$ wp-login.php$1 [L]
</IfModule>
#==== SITEGUARD_RENAME_LOGIN_SETTINGS_END
#SITEGUARD_PLUGIN_SETTINGS_END
```

Webサーバが Nginx の場合は、`.htaccess` が有効にならないので、以下のような感じで設定追加しましょう。
単純に Nginx の `rewrite` に書き換えただけ。

```
rewrite ^/wp-signup\.php$ /404-siteguard break;
rewrite ^/wp-activate\.php$ /404-siteguard break;
rewrite ^/login-xxxx(.*)$ /wp-login.php$1 break;
```
Node.js Socket.io 基本

# Socket.ioの基本

## 初めに
socketは、一つのブラウザにログインした人(ブラウザ)を識別するもの
オブジェクト指向のインスタンスと思って良いと思う。

socketには、様々な便利なメソッドが入っていて
複数人同時の接続をsocketで一人ずつ確実に処理できる。

## 環境構築
まず作業ディレクトリを作る。

```:bash
$ mkdir node-test
$ cd node-test
```
Socket.ioの環境構築は、二つ方法がある。
1.インストールをその場でできるならする。

```:bash
$ npm install socket.io
```

2.package.jsを書いてインストール

```json
{
  "name": "node-test",
  "version": "0.0.1",
  "description": "chat server",
  "dependencies": {
    "socket.io": "~0.9.6"
  }
}
```

```:bash
$ npm install
```


## イベント処理の考え方
例えばブラウザからhtmlのinputでtextを送る時
「ブラウザ」→「サーバ」にデータが送られる。
### イベント送信
「ブラウザ」は、イベントが起きた時にソケットにデータを付与して送信する
そのメソッドがemit()というもの

```js:socket.io
socket.emit('イベント名', データ);
```
イベント名は、自分でつけていい。
データは、一つでもいいし、Json形式を使って複数のデータも渡せる。

### イベント受信
「サーバ」は、指定のイベント名からデータが送られてくるのを待ち続ける。
データが送られてきた時に関数の引数としてデータを受信し、メソッドを動かす

```js:socket.io
socket.on('イベント名', function(引数) {
});
```

### イベントを管理する
socketは、初めからsocket.idというものが振られていて
それぞれのsocketのインスタンスを識別できる
これを利用してリストの識別をsocket.idで識別することで
単体の情報がしっかりと管理できる。
bundle installしたらgem install pgしてと言われたけど、素直にやっても解決しなかったときにやった方法

# 状況

herokuにアップする過程でGemfileを書き換えたのでbundle install しようとしたら失敗

**An error occurred while installing pg (1.0.0), and Bundler cannot continue.
Make sure that `gem install pg -v '1.0.0'` succeeds before bundling.**
と言われたので素直に

```
gem install pg -v '1.0.0'
```
とした後にbundle installしてみたものの、再度下記のエラーが返って来た。

**An error occurred while installing pg (1.0.0), and Bundler cannot continue.
Make sure that `gem install pg -v '1.0.0'` succeeds before bundling.**
ググってみたところ、ポスグレがinstallされていなかった模様。。

```
brew install postgresql
```

で解決しました。

[こちら](https://qiita.com/andmorefine/items/a4b1762ec86b831f63ef)を参考にしました。
なんでもアートっぽくなるシェーダ

シェーダの勉強の勉強中です。
自作ポストエフェクト作ってみました。

#実装
```c#:
Shader "Custom/SplitPixel" {
        Properties {
        _MainTex ("Source", 2D) = "white" {}
        _Size ("Size", int) = 30
    }
    SubShader {
        Pass{
            CGPROGRAM
            #pragma vertex vert_img
            #pragma fragment frag
            #include "UnityCG.cginc"

            struct v2f {
                float4 pos : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float _Size;

            fixed4 frag(v2f i) : SV_TARGET {
				float u = i.uv.x;
				float v = i.uv.y;
				float interval = 1.0 / _Size;
				int x = u / interval;
				int y = v / interval;
				u = (interval * x) + (interval * (x + 1)) - u;
				v = (interval * y) + (interval * (y + 1)) - v;
				return tex2D(_MainTex, float2(u, v));
            }
            ENDCG
        }
    }
    FallBack Off
}
```

何をしているかというと画像を分割して180度回転させているだけです。
細かさは自分で設定できます。
イメージ画像
![名称未設定 4.png](https://qiita-image-store.s3.amazonaws.com/0/146726/249387a0-42c1-ee2b-d811-bc4f62d5a0d4.png)

#Instagramで見つけ、面白そうだったので実装してみた。
https://www.instagram.com/p/BgkxvNXBJ8f/?hl=ja&taken-by=limitart

#使い方
1.PostEffect.csをMainCameraに追加。
2.マテリアルを追加。

```c#:PostEffect.cs
using UnityEngine;
using System.Collections;

public class PostEffect : MonoBehaviour {

	public Material pixel;

	void OnRenderImage(RenderTexture src, RenderTexture dest)
	{
		Graphics.Blit (src, dest, pixel);
	}
}

```

<img width="431" alt="スクリーンショット 2018-04-02 19.19.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/146726/5e672694-464c-ce0a-8f00-a147eb5173e6.png">

# GitHub
https://github.com/kanechiru/PixelArtShader

Shaderの勉強を始めたばかりなので、訂正箇所あればコメントください！
react-native-web + TypeScript のサンプル

これが正しいやり方なのか良くわからないが、動いたのでメモ。目標は

* TypeScript でコードを書く。react-native-typescript-transformer を使う。
* 携帯 Native アプリとして実行する。Expo を使いたくないので create-react-native-app は使わない。
* Web アプリとして実行する。プロジェクトは create-react-app で作成。
    * create-react-app が対応しているので最低限の設定で react-native-web を利用可。

意外とややこしかったので作業結果をアップした https://github.com/propella/ReactNativeTest

## 普通に react-native のプロジェクトを作る

    brew install node watchman yarn
    npm install -g react-native-cli
    react-native init ReactNativeTest
    cd ReactNativeTest
    react-native run-ios

## React Native を TypeScript で書く。

    yarn add --dev react-native-typescript-transformer typescript @types/react @types/react-native

あとは <https://github.com/ds300/react-native-typescript-transformer> の通りに

* tsconfig.json
* rn-cli.config.js

を作成

コンポーネントの拡張子を変える。

    mv App.js App.tsx

import 文をちょっと変えないとビルド出来ませんでした。

    import * as React from 'react';
    const Component = React.Component;

## React Native のテストを TypeScript で書く

基本 <https://github.com/kulshekhar/ts-jest#react-native> の通りだが、慣れてないと難しい。。。

    yarn add --dev ts-jest @types/jest @types/react-test-renderer

package.json の jest セクションはこんな感じ

```javascript
"jest": {
    "preset": "react-native",
    "transform": {
      "^.+\\.jsx?$": "<rootDir>/node_modules/babel-jest",
      "^.+\\.tsx?$": "ts-jest"
    },
    "testRegex": "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$",
    "moduleFileExtensions": [
      "ts",
      "tsx",
      "js",
      "jsx",
      "json",
      "node"
    ],
    "globals": {
      "ts-jest": {
        "useBabelrc": true
      }
    }
  }
```

サンプルでついてるテストケースも微妙にうごかないので修正

    mv __tests__/app.js __tests__/app.tsx

```typescript
import 'react-native';
import * as React from 'react';
import App from '../src/App';

// Note: test renderer must be required after react-native.
import { create } from 'react-test-renderer';

it('renders correctly', () => {
  create(
    <App />
  );
});
```

## react-native-web と react-script-ts で web 化

    yarn add react-native-web react-dom react-scripts-ts

別途 `npx create-react-app my-app --scripts-version=react-scripts-ts` で作っておいたプロジェクトから足りないファイルを手動で追加してゆく。

```
mkdir public
cp ../my-app/public/index.html public/index.html
cp ../my-app/tsconfig.json tsconfig.json 
cp ../my-app/tslint.json tslint.json
```

src/index.tsx の作成 

```typescript
import App from './App';
import { AppRegistry } from 'react-native';
p
// register the app
AppRegistry.registerComponent('App', () => App);

AppRegistry.runApplication('App', {
  initialProps: {},
  rootTag: document.getElementById('root')
});
```

    mv App.tsx src/

パスも合わせて修正する。

その他雑多な作業

* `Property 'geolocation' must be of type 'Geolocation'` エラーが出る場合 tsconfig.json に以下追加
    * `"skipLibCheck": true`
* src/App.tsx で styles の定義を前に持ってくる。
* tsconfig.json から `"rootDir": "src"` を削除

起動

    npx react-scripts-ts start

ソースコードを更新すると Web ブラウザと iPhone Simulator 同時に表示が変わる。これは面白い。

## 参考

* [React Native for WebとExpoを組み合わせてピコピコさせてみたよ](https://qiita.com/Nkzn/items/8e31efe0ebafa8038bde)
    * webpack を使った例。やりたい事が大体同じで大変役にたった。こっちの方が柔軟で良いかも。
国税庁へのリンクを国立国会図書館のWARPへのリンクに書き換える

# はじめに

[国税庁のウェブサイトがリニューアルされて阿鼻叫喚](https://internet.watch.impress.co.jp/docs/yajiuma/1114712.html) とのことです。なんとかしてみましょう。

# 手順

## 1. Tampermonkey のインストール

お使いのブラウザに [Tampermonkey](http://tampermonkey.net/) をインストールします。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/6eb1fd40-c698-0742-749a-ae1f502175ba.png)


## 2. ユーザスクリプトのインストール

以下の URL をクリックします。

<https://gist.github.com/frogcat/9adb175f60198d3e260cfb582838c6d4/raw/c51a348f00b6da5034b2fe2d35e318b1c1e75c8a/nta.go.jp_to_warp.user.js>

すると以下のようにユーザスクリプトのインストール確認画面が出てくるので、**インストール** ボタンをクリックしてインストールします

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/00bd1545-7212-fa61-94d1-f1f9f568f775.png)

以上で完了です。

これでお使いのブラウザでページを表示する際、 <https://www.nta.go.jp/taxanswer/shotoku/1524.htm> のような、旧国税庁サイトへのリンクが含まれていると<http://warp.da.ndl.go.jp/info:ndljp/pid/11056018/www.nta.go.jp/taxanswer/shotoku/1524.htm> のような、国立国会図書館の WARP へのリンクに書き換えられます。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/82494/2d9a15fe-97ff-75d1-c437-6b1e1e357332.png)

# メモ

- WARP は国立国会図書館の運営する、官公庁サイトなどをアーカイブするサービスです
- 国の機関については [月に一回](http://warp.da.ndl.go.jp/info/WARP_qanda.html#01_02) アーカイブが作成されるとのことです
- 上のユーザスクリプトは ~~2018-02-01~~ 2018-03-01 時点のアーカイブにリンク先を変更しています
- 不要になったら Tampermonkey の管理メニューからユーザスクリプトを削除するか、Tampermonkey ごとアンインストールしてしまいましょう
laravel new で新規プロジェクトが作成できないとき

#経緯
laravelコマンドで新規プロジェクトを作成しようとしましたが、以下のエラーで作成ができませんでした。

```
Crafting application...
PHP Fatal error:  Cannot use lexical variable $eventName as a parameter name in /Users/pirothy/.composer/vendor/guzzlehttp/guzzle/src/Event/Emitter.php on line 49

Fatal error: Cannot use lexical variable $eventName as a parameter name in /Users/pirothy/.composer/vendor/guzzlehttp/guzzle/src/Event/Emitter.php on line 49
```

#解決
一部のlaravelで使うプロジェクトが古くなっていたのが原因だったみたいです。
以下コマンドを打てば解決します。
`composer global update`

以上です。
CacheManagerを使い分ける

## 用途に応じてCacheManagerの使い分けをしたい。

### 例

defaultで`ConcurrentMapCacheManager`を使い、`CacheManager`の指定で`RedisCacheManager`を使えるようにする。

### Config

```java
@Configuration
public class CacheConfig {

    @Primary
    @Bean
    public CacheManager cacheManager() {
        ConcurrentMapCacheManager cacheManager = new ConcurrentMapCacheManager();
        return cacheManager;
    }

    @Bean
    public CacheManager redisCacheManager(RedisTemplate<String, String> redisTemplate) {
        RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
        cacheManager.setDefaultExpiration(3600);
        return cacheManager;
    }
}
```

`@Primary`がついたものを同じ型のBeanのなかで優先することができます。
逆に指定せずに同じ型のBeanが複数定義されていると起動時に怒られます。

### Cache

```java

@Cacheable(cacheNames = "default")
public String default() {
    return "DEFAULT";
}

@Cacheable(cacheNames = "redis", cacheManager = "redisCacheManager")
public String redis() {
    return "REDIS";
}
```

今回の例だと、`cacheManager`指定なしで`ConcurrentMapCacheManager`が使われ
`cacheManager`を指定することで、`RedisCacheManager`を使うといったことが可能。

応用することで用途に応じてCacheManagerを使い分けができます。
PHPUnitでHTMLをDOMでパースしてテスト

PHPでなんらかのHTMLを出力するコードをテストする際に、これまでは正規表現とかでいい加減なチェックをしてたんですが、割と大きめなHTMLを出す際にいい加減不安なのでDOMを使ってチェックすることにしました。

当初はPHP本体の `DOMDocument::loadHTML` でやろうとしたんですが、HTML5
 の `<section>` を使うと `DOMDocument::loadHTML(): Tag section invalid in Entity, line: 1` と怒られてしまって断念。

その後いろいろ試した結果以下の2つのライブラリを使用すれば CSS セレクタでいい感じにチェックできました。

* `symfony/dom-crawler`
* `symfony/css-selector`

いつも思うんですが、Symfony 先輩さすがですね。

## 依存関係のインストール

まず、上の2つを `composer` でインストール。

```
$ composer require symfony/dom-crawler symfony/css-selector --dev
```

今回はテストで使うので `--dev` 付きで。

## DOMを返すメソッドをテストケースに書く

まず、HTML を渡すと DOM を返してくれるメソッドを用意します。`<html></html>` とかで囲ってあげなくてもいいみたい。

```php
<?php
class Sample_Test extends UnitTestCase
{
	private function dom( $html )
	{
		$dom = new Symfony\Component\DomCrawler\Crawler();
		$dom->addHTMLContent( $html, "UTF-8" );
		return $dom;
	}
}
```

## テストを書く

次に実際のテストを書きます。`test_html()` というメソッドがそれ。
`do_something()`は何らかのHTMLを返す関数です。

```php
<?php
class Sample_Test extends UnitTestCase
{
	public function test_html()
	{
		$result = do_something();
		$dom = $this->dom( $result );

		$this->assertSame( 1, count( $dom->filter( '.col-3' ) ) );
		$this->assertSame( 6, count( $dom->filter( 'section.item' ) ) );
	}

	private function dom( $html )
	{
		$dom = new Symfony\Component\DomCrawler\Crawler();
		$dom->addHTMLContent( $html, "UTF-8" );
		return $dom;
	}
}
```


この例では、CSSセレクタを使用して、そのセレクタにマッチする要素が期待した数だけあるかをチェックしています。

```php

$this->assertSame( 1, count( $dom->filter( '.col-3' ) ) );
$this->assertSame( 6, count( $dom->filter( 'section.item' ) ) );
```

ドキュメントは以下。

https://symfony.com/doc/current/components/dom_crawler.html

## このテストでできないこと。

HTMLの構文チェックはできません。たとえば閉じタグがないタグを置いても頑張ってパースしてくれてしまいます。
そして `<hoge>` みたいに適当な要素をおいても同じく頑張ってくれてしまいます。

以下のようなメソッドで閉じタグ漏れぐらいはチェックできるかも。

```php
private function assertMaybeValidHTML( $html )
{
	$html = str_replace( 'section', 'div', $html );
	$html = str_replace( 'aside', 'div', $html );
	$dom = new DOMDocument();
	$dom->loadHTML( '<html><body>' . $html . '</body></html>' );
}
```
SwiftのバージョンによってdSYMのサイズが変わる

realm-cocoaをcarthageでビルドした時のdSYMのサイズ

|Swift|dsym|size|
|---|---|---|
|Swift4.0.3|Realm.framework.dSYM|92.8MB|
|Swift4.1|Realm.framework.dSYM|125.6MB|

なんでだろ
python3+openCVでイラストと写真の識別

# はじめ
　python3とopenCVを使ってjpg画像が"イラスト"なのか"写真"なのか識別してみました．思っていたよりも参考資料がなかったので，ほぼ自前でやりました．

# 環境
・ Python 3.6.4
・ Windows 10

　必要なモジュールは以下のとおりです
・opencv-python

　opencv-pythonはpipでインストールできます．

```
$ pip install opencv-python
```

# 識別の手順

1. 画像ファイルを読み込みむ
2. 読み込んだ画像（オリジナル画像）をグレイスケール化し以下の画像を得る．（エッジ検出はキャニー法です）
    3. グレイスケール化した画像からエッジ検出した画像（can_img）
    4. グレイスケール化した画像をガウシアンフィルタでぼかしてからエッジ検出した画像(gau_can_img)
    5. グレイスケール化した画像をメディアンフィルタでぼかしてからエッジ検出した画像(med_can_img)  
6. can_imgとgau_can_imgとの差，can_imgとmed_can_imgとの差を計算し，その差を足す．  
（イラストに比べて写真のほうがピントなどでぼけている部分があり，ぼかしを入れる前後で検出されるエッジの変化が大きいと予想したためこの差を識別に使用しました．また，イラストでは描かれているものの輪郭がはっきりしているものが多いと思ったりもしました）
7. オリジナル画像から各画素のRGBを取得し，最も多く現れる色がどのくらい頻度で現れているのかを算出する．  
（イラストのほうが写真に比べて同じ色が含まれている量が多いと予想したためです）
8. 3,4で得られた値からスコアを算出して，イラストか写真か判別する．

## まとめると...
　「"ぼかしによるエッジ検出量の差"と"画像中で最も多く現れる色の出現頻度"をもとにスコアを算出し，そのスコアが一定以上ならイラスト，一定未満なら写真として識別する」
ということです．

## スコアの算出
　スコアは以下の式で算出しています．SCOREが0.5より高ければイラスト，低ければ写真と識別されます．  
SCORE = ((1 / diff_result) * 0.8 + (color_result / 100) * 0.2) * 0.625

>・ diff_result:　手順3で得られた結果
・ color_result: 手順4で得られた結果 

　diff_resultは画像をぼかしたときにエッジ検出量がどのくらい減ったかというものなので，この値が低いほどイラストとしてのスコアが高くなります．
　color_resultは画像中で最も多く現れる色の出現頻度なので，この値が高いほどイラストしてのスコアが高くなります．

　上のスコア算出の計算式は値を見ながら調整したものなので，最適ではないと思います．はい．


#　画像データ
　画像データはpixivやフリーの写真素材サイトなどからとってきました.

# ソースコード
　githubにおいてあります.
https://github.com/suzuryu/ImageIdentification.git

　画像サイズが大きい場合は,画像サイズを1/2に縮小しています.
識別はかなり大きな画像でなければ０～１０秒程度で終わります．
（4032*3024より大きいものはわからないです．はい）

# 実行
ex) 実行例
　イラストは著作権的なのが面倒なのでイラストやから．

```
$ python identifiesImage.py exmaple.jpg
score : 0.476 -->picture
```
![example.jpg](https://qiita-image-store.s3.amazonaws.com/0/176347/daa3e3de-2cf1-7794-143c-d04c27fca7e9.jpeg)

```
$ python identifiesImage.py exmaple2.jpg
score : 0.351 -->picture
```

![IMG_0262.JPG](https://qiita-image-store.s3.amazonaws.com/0/176347/23502afc-97d4-89d3-897d-69d3d2152aca.jpeg)

```
$ python identifiesImage.py exmaple3.jpg
score : 0.918 -->illust
```

![example3.jpg](https://qiita-image-store.s3.amazonaws.com/0/176347/4d2043d3-86ff-639c-f5ce-b8f109cf21a7.jpeg)


# 結果　意外と良い
> score: 0.8581 画像枚数: 2630枚 正解枚数: 2557枚
写真判定: 0.795
イラスト判定: 0.82

　約2600件の画像で全体として識別率85%と結構いい感じに識別できました．写真をイラストとして識別しちゃうのが多かったです.
相性の悪いイラストや写真だと間違った識別をしやすくなると思います．
（写実的なイラスト，証明写真,　風景写真・イラスト etc..）
[ポエム]2年間学生の開発チームを見てきた振り返り

# はじめに

　今日は4月2日ってことで新社会人としてスタートを切る人結構多いんじゃないですかね。自分は2年程前から会社員として働く傍ら、某大学院で技術アドバイザー兼アジャイルのメンターや学生が作ったプロダクトの審査委員をやってきました。学校で教えてる内容も座学は当然あるものの、リーンキャンバスを書いたりユーザーインタビューをしたり、プロダクトを作るだけでなくどう顧客に価値を与えるかチームで考えながら進める、かなり実践に即した講座になっていて正直自分が受講したいくらいの内容でした。
　というわけで自分が見てきた学生たちも卒業し本日から新社会人として働きだすこのタイミングでちょっと振り返りを書いてみようかと。


# 振り返り

## 学生ならではのチームビルディングの難しさ

　社会人なら会社のビジョンが入社時点で明確化されていたり役職等の上下関係が存在するが、学生は立場等が全員平等かつ目的もそれぞれバラバラの為、ある意味これがチームビルディングの阻害要因になっているケースが見られた。

* ただ単位取れればいい生徒といい成績取りたい生徒
* 自分のアイディア最強
* バックグラウンドのスキルの差
* （主に留学生の）言語の壁

　但しこの壁を乗り越えたチームは全員フラットであるが為に、議論する際に本当に建設的に話し合いをしていて、社会人以上にPDCAを高速に回しているように見受けられた。


## 振り回す大人と振り回される生徒

　学生にとっては社会人の影響力ってほんとに強くて、言われたことを盲目的に取り入れてしまったり、ある人とある人が言ってることが矛盾するんですけど・・・みたいな感じで途方に暮れるケースが多く、君たち誰のためにモノ作ってるんだよってケースが度々あった。特にイノベーションおじさんやシンギュラリティおじさんは確かに経歴上すごいんだけど、学生に価値観を押し付けてくる傾向が強く、こうならないように気を付けようと思った（自戒）


## ニーズとシーズのジレンマ

　本当はニーズから検証したいところだが、学校という関係上どうしてもテーマみたいなものがあり、シーズスタートとならざるを得ない場合があった。シーズありきからスタートすると問題発見が本当に難しく、実際にプロダクト開発に着手するまでに半年以上期間を要したチームもあった。


## 課題からいきなりソリューション行っちゃう

　これは学生に限らず・・・、課題発見からいきなりソリューション作ったりし始めて問題の深掘りが足りなかったり、誰が嬉しいの？ってことに答えられないケースが度々あり、特に技術的に精通している学生ほどこうなる傾向が高いように思えた。いきなりソリューション作りたくなっちゃう気持ちはすごい分かるんだけどね。


## 社会人には到底思いつかないアイディアだったり実装方法だったり

　これに関しては深く書くのはやめよう・・・

* 社会的に大丈夫なのかパターン（ex.傘盗まれたときに仕返し）
* [プロダクトの名前がすごいパターン](https://twitter.com/kakeigakuen)
* 技術自体がすごいパターン（サーバクライアントどっちもC++なんだけど生ソケットで個人情報やりとり）
* 他いろいろ


## その他

　他にも色々経験させてもらった。自分が学生だったころをすごい思い出して切なくなってしまった。

* 恋の相談
* 女子大の研究室でぬいぐるみにトランジスタが刺さってた
* 学生の親御さんと一緒に学祭見て回ったり
* 我が家でたこ焼きしながらガルパン上映会したり


# おわりに

　最初はアドバイザーみたいな形でスタートしたにも関わらず、こちらが勉強になることが多くて本当にいい経験させてもらいました。関係者の皆さんにも大変お世話になりました。そして学生のみんな、今更ながら卒業おめでとう！

　また本年度以降も積極的に関わっていければと思っているので、よろしくお願いします！

**まとまりのない文章ですみません＼(^o^)／**
超基本　GitHub投稿するための準備

相変わらず超基本をメモとして書いておきます。
#1　GitHubに新しいリポジトリを作る
GitHubのホームページに行ってNew repositryのボタンをポチっとする。
Repository nameのところに名前を入れてクリエイト。

#2 ターミナルでのgit操作
ざっと流れを書くと

```git
git init
git add README.md
git commit -m "first commit"
git remote add origin git@github.com:kensukemt2/achieve.git
git push -u origin master
```

ホームディレクトリは作成不要です。
勝手に作ります。よく忘れて２重にしてしまってます。
反対にGitHubからコードを落としてくるときには
```
git clone [リポジトリ] [ディレクトリ]
git remote add [name] [url]
```

remoteのところは最初のコードをあげたリポジトリと同じなら不要。
名前をつけたリポジトリを調べたいときには

```
git remote -v
```

originが今何かとかでよくお世話になります。
Puppeteerでlibnss3.so: version `NSS_3.22' not foundと出たら

# 結論

```bash
apt-get update
apt-get upgrade
```

更新する。

# 環境

* Ubuntu 14.04.5 LTS, Trusty Tahr
* Node.js v9.10.1
* Puppeteer 1.5.1

# 経緯

[puppeteer/troubleshooting.md at master · GoogleChrome/puppeteer](https://github.com/GoogleChrome/puppeteer/blob/master/docs/troubleshooting.md)

の依存物をまとめて

`apt-get install gconf-service libasound2 libatk1.0-0 libc6 libcairo2 libcups2 libdbus-1-3 libexpat1 libfontconfig1 libgcc1 libgconf-2-4 libgdk-pixbuf2.0-0 libglib2.0-0 libgtk-3-0 libnspr4 libpango-1.0-0 libpangocairo-1.0-0 libstdc++6 libx11-6 libx11-xcb1 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxext6 libxfixes3 libxi6 libxrandr2 libxrender1 libxss1 libxtst6 ca-certificates fonts-liberation libappindicator1 libnss3 lsb-release xdg-utils wget`

で入れた後、実行したら出たエラーがタイトル。

[69345 - Chrome fails to start, error: "/usr/lib/libnss3.so.1d: version `NSS_3.12.6' not found" - chromium - Monorail](https://bugs.chromium.org/p/chromium/issues/detail?id=69345)

>This issue is fixed for me.
>
>After the package update today, my chrome starts and appears to work normally.

とあったので、

```bash
apt-get update
apt-get upgrade
```

で更新すると解消した。

# 参考

* [yum update と yum upgradeの違い（ついでにDebianも） - Qiita](https://qiita.com/mokrai/items/4e0597505097538b6e2c#%E3%81%8A%E3%81%BE%E3%81%91debian%E3%81%A7%E3%81%AF)
* [Ubuntuのバージョン確認 - Qiita](https://qiita.com/glires/items/a2a07565207509af0e83)
REGEXP_REPLACE()でdoes not existsになる現象の調査と結果

AWS Redshiftで実行していたSQLを検証環境用のDB(Postgresql@9.6)で実行したところエラーがでて困った話し。
エラー内容と実行したSQLは↓のようなイメージ。

```sql
SELECT REGEXP_REPLACE(json, '\\{|\\}') AS `json_data` FROM `log_table` ;


ERROR:  function regexp_replace(text, unknown) does not exist
行 1:   REGEXP_REPLACE(json, '\\{|\\...
                              ^
HINT:  No function matches the given name and argument types. You might need to add explicit type casts.
```

## 結論:

原因は2つ。

- REGEXP_REPLACE()の第二引数`pattern`がunknownになっているのでわかると思うが`'\\{|\\}'`が文字列として認識できていない。
- PostgresqlのREGEXP_REPLACE()は第三引数までが必須引数。

### 文字列として認識できない問題の解決策:
Hintにあるようにunknownになっている第二引数を文字列で型キャストしてやる。
型キャストする方法は2つある？みたいで`[カラム名]::[型名]`か`CAST([カラム名] AS [型名])`してやればいい(後者は試していない)

```sql
SELECT REGEXP_REPLACE(json, '\\{|\\}'::text) AS `json_data` FROM `log_table` ;
```

これで`ERROR:`と表示された行が解消した。

### PostgresqlのREGEXP_REPLACE()は第三引数までが必須引数。

全ての元凶はこれだった。
Postgresにも`REGEXP_REPLACE`あるじゃん！とPostgresのドキュメントで確認していたのだけど引数までは確認していなくてしばらくハマった。

[REGEXP_REPLACE 関数](https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/REGEXP_REPLACE.html)では第三引数は省略可能だがPostgresの[
9.4. 文字列関数と演算子](https://www.postgresql.jp/document/9.6/html/functions-string.html)の`reqexp_replace`の項目では第三引数は省略可能でないのが確認できる。

ということで第三引数を指定(今回は`{}`を除去したかったので空文字を指定)することで解決した。

2つ原因があったことに気づくまでに時間がかかってしまったのが反省点。
SQLの方言にたまに遭遇すると気づくまでに時間がかかるのをなんとかしたい。
IntelliJ IDEA 2018.1でKotlinの型のヒント情報を表示する

Preferencesの[Editor]-[General]-[Appearance]から[Show parameter name hints]にチェックを入れて、[Configure...]をクリックして表示されるダイアログでKotlinを選択してオプションに色々チェックを入れる。

こんな感じで見えていたものが、

![FunctionTest.kt [kotlin-learning_test] 2018-04-02 17-58-31.png](https://qiita-image-store.s3.amazonaws.com/0/1958/f1e74d85-9035-5965-8473-44847d6f318e.png)

こんな感じで見えるようになる。

![FunctionTest.kt [kotlin-learning_test] 2018-04-02 17-59-59.png](https://qiita-image-store.s3.amazonaws.com/0/1958/cbb131c5-047f-4048-79ad-8a9d506e90d1.png)
[さくらVPS]CentOS7にLet's EncryptのSSL証明書を導入する

#はじめに
さくらVPSを新しく借りたのでCentOS7 + nginxの環境で
Let's EncryptのSSL証明書を導入する。
# 環境
OS: CentOS Linux release 7.4
WebServer: nginx 1.13.9
DocumentRoot: /var/www/html
Domain: www.example.com

# install
```
# cd /usr/local
# git clone https://github.com/certbot/certbot.git
```

# 証明書の取得
```
# cd certbot
# ./certbot-auto -n certonly --webroot -w /var/www/html -d www.example.com -m example@example.com --agree-tos
```

## optionについて
| 1 | 2 | 3 |
|:-:|:-:|:-:|
|certonly| サブコマンド |SSL/TLS サーバ証明書の取得のみを行う。
|-n (--noninteractive)   | 一般オプション  |クライアントソフトウェアの実行時に、ユーザーからの入力を一切求めない。
|-m --email   | 一般オプション  | トラブルや証明書の期限が近いなどの連絡先のメールアドレスを指定する。
|-w (--webroot-path)   | プラグイン関係のオプション  | ドキュメントルートのパスを指定する。
|-d (--domain)    | 一般オプション  | SSL/TLS サーバ証明書の取得を申請するドメイン名を指定する。
|--webroot   | プラグイン関係のオプション  | ドキュメントルート以下に認証用ファイルを生成する。
|--agree-tos    | 自動化オプション | Let's Encrypt の利用規約に同意する。


# Nginx（ついでにhttp2）
ついでにhttp2も（listenに「http2」を追加）

```/etc/nginx/conf.d/ssl.conf
server {
    listen 443 ssl http2;
    server_name www.example.com;
    ssl_certificate     /etc/letsencrypt/live/www.example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/www.example.com/privkey.pem;
    root /var/www/html;

    location / {
        index index.php index.html index.htm;
    }

    location = /50x.html {
        root /usr/share/nginx/html;
    }

    location ~ \.php$ {
        fastcgi_pass  unix:/var/run/php-fpm/php-fpm.sock;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include       fastcgi_params;
    }
}
```

# Port(443)の解放
portを解放していなければ解放する

```
# firewall-cmd --add-service=https --permanent
# systemctl restart firewalld
```



# 証明書の更新
```
# ./certbot-auto renew --webroot -w /var/www/html
```
ちなみに証明書の有効期限が近くないと
「Cert not yet due for renewal」
このようなメッセージが出て更新できない。

# 参考
[Let's Encrypt 総合ポータル](https://letsencrypt.jp/)
[CentOS7でLet's Encryptを使う](https://qiita.com/yasushi00/items/40bdaf8f05017e212325)
[Let's Encrypt で Nginx にSSLを設定する](https://qiita.com/HeRo/items/f9eb8d8a08d4d5b63ee9)
超基本　Ruby on Rails でアプリを作る際の流れ

rails でアプリを作る手順を忘れないように書いておきます。
#1.アプリケーションを作る
アプリを作ります。データベースをPostgreSQLを使う場合は以下になります。
```rails new sample -d postgresql
```
#2.generateで生成
次にScaffoldにてアプリのひな型を作っていきます。コントローラ、モデル、ビューを作ってくれて便利。
```rails g scaffold sample title:text content:text
```
もちろん個別に
```
rails g controller samples
rails g model sample title:text content:text
```
作ってもOK。

Scaffoldではデータベースはできていないのでデータベースを作ります。
```rails db:create```
つづいてマイグレーションを行います。
```rails db:migrate```
#3 ルーティングの設定
config/routes.rb
の編集をします。以下の２行を追加します。
```root to: 'blogs#index'
resources :blogs
```
１行目はルートのアクセス先を指定。２行目はRESTfulなURLを自動生成しています。

#4. コントローラー、モデル、ビューの記述
最後に中身を作ります。各々必要なものを書いてください。
まずはコントローラにアクションを記述しましょう。
/app/controllers/の下にあるファイルです

```ruby
class SamplesController < ApplicationController
  def new
  end
end
```
newがアクションの名前です。

次にモデルを記述します。/app/models/の下にあるファイルです。
ここにはバリデーションなど書きます。
そしてビューファイル。html形式で書いていきます。