OmniAICreator/Qiita-1.07M huggingface dataset:
Googleスプレッドシートの正規表現で先読み後読みが使えない問題をなんとかした

Googleスプレッドシートの正規表現で先読み後読みが使えない問題をなんとかした

# はじめに
コメントアウトを検出するために正規表現を使いましたが、Cの`#define`まで引っかかったので否定先読みを試みたらエラーが表示されました。調べてみるとサポートしていなかったようで、それをなんとかした話です。

```
https://github.com/google/re2/blob/master/doc/syntax.txt#L82-L85

(?=re)	before text matching «re» NOT SUPPORTED
(?!re)	before text not matching «re» NOT SUPPORTED
(?<=re)	after text matching «re» NOT SUPPORTED
(?<!re)	after text not matching «re» NOT SUPPORTED
```

# やったこと
## エラー

否定先読みがサポートされていないので失敗

```
=REGEXMATCH("#define HOST 192.168.1.10", "(?!#define)#")

=> エラー
関数 REGEXMATCH のパラメータ 2 の値「(?!#define)#」は無効な正規表現です。
```

## 成功
否定先読みの部分をREGEXREPLACEで置換すればいけそうです。

```
=REGEXMATCH(REGEXREPLACE("#define HOST 192.168.1.10","#define",""), "#")
=> FALSE

=REGEXMATCH(REGEXREPLACE("#server_address=192.168.1.1","#define",""), "#")
=> TRUE

```
kivy FloatLayout でのImageの配置(Responsive)

FloatLayout内にてImage widgetを以下の要求に答える表示をしたい
ほとんどの資料は、使用する画像が決まっているためか、size、size_hintが固定で以下の要求の設定パターンが見つからなかったため記録に残します。

# 要求
- 任意の場所に表示
- 使用する画像はサイズ・アスクペクト比を指定しない
- アスペクト比を維持して表示

要はWEBでよくいうレスポンシブ

## 設定例：左上、横サイズ25%
### 失敗例

**設定内容**

```
#:kivy 1.10
#-*- coding: utf-8 -*-

<Logo@Image>:
    size_hint:0.25,None
    source:'./logo.jpg'
    allow_stretch:True
    keep_ratio: True
    canvas.before:
        Color:
            rgba: 1, 0, 0, 0.5
        Rectangle:
            size: self.size
            pos: self.pos
            
FloatLayout:
    Logo:
        pos_hint:{'x':0,'top':1}
```


- pos_hint:{'x':0,'top':1}　　左上指定
- size_hint:0.25,None　　Width指定、Heightは未指定
- allow_stretch:True　　サイズいっぱいに表示
- keep_ratio: True アスペクト比を維持

**結果**
左上にくっつかずに表示されている（赤枠はImage Widgetの範囲）
**原因はデフォルト設定の　size:100,100　のheight部分が反映されているため**
floatlayout は size_hint > size で反映される
今回、height部分はNoneのため、sizeのheightが反映されているために画像を超えてImage Widgetが設定された。

![スクリーンショット 2018-07-10 12.39.32.png](https://qiita-image-store.s3.amazonaws.com/0/120613/eeec0169-3d2f-3989-8861-9dcaa9b4871e.png)

---
### 成功例1(height指定)
**設定内容**
失敗例に追加でheightを指定
指定方法は画像の比率（image_ratio）とImage WidgetのWidthから高さを算出して設定

**追記 2018/7/10**
Windowサイズからはみ出す場合がある（色々試してたら発生した・・・）
特に気にしなくてもいいかもしれないけど対策した成功例２を掲載

- height: self.width/self.image_ratio

```
#:kivy 1.10
#-*- coding: utf-8 -*-

<Logo@Image>:
    size_hint:0.25,None
    source:'./logo.jpg'
    allow_stretch:True
    keep_ratio: True
    canvas.before:
        Color:
            rgba: 1, 0, 0, 0.5
        Rectangle:
            size: self.size
            pos: self.pos
            
FloatLayout:
    Logo:
        pos_hint:{'x':0,'top':1}
        height: self.width/self.image_ratio
```


![スクリーンショット 2018-07-10 12.56.38.png](https://qiita-image-store.s3.amazonaws.com/0/120613/88bd8a45-f882-3e46-b9b7-d34c6cf7eebd.png)


---
### 成功例2(size_hint_max指定)
**設定内容**
成功例１の際、アスペクト比・Windowサイズによってはみ出てしまう
その対策バージョン（画面内に収まる＋適切なWidget範囲）　

**2018/7/11 
縦横両方の可変に対応した方法はうまくいかない時があったので修正
大きくずらさない限りは大丈夫なはずです**

```
#:kivy 1.10
#-*- coding: utf-8 -*-

<Logo@Image>:
    size_hint:0.25,1
    size_hint_max:self.parent.height*self.image_ratio,self.width/self.image_ratio
    source:'./img/logo.jpg'
    allow_stretch:True
    keep_ratio: True
    canvas.before:
        Color:
            rgba: 1, 0, 0, 0.5
        Rectangle:
            size: self.size
            pos: self.pos
            
FloatLayout:
    Logo:
        pos_hint:{'x':0,'top':1}
    　　　　　　　　　　　　
```
size_hintにてNoneから１に変更
size_hint_max_yにて高さを調整する。


#### Widthを可変に調整したい場合（例　高さ２５％）

```
size_hint:1,0.25
size_hint_max:self.height*self.image_ratio,self.parent.width/self.image_ratio
```

---
### あとがき
height:auto とかそうゆうのがほしかった。
他に方法あるかもしれないけど満足
よほどじゃない限り大丈夫かも・・・
クラスを指定するいろいろな方法（スタブ）

自分用メモです…。不備あると思いますのでもっと調べてからまとめます。

# 何がしたい？

PHPってホントにインタプリタだなーと思うのが、クラス名や関数名を文字列で指定できたりするところ。たとえばあるインスタンスが取り扱うクラスを「クラス名」で注入することができたりするんですよね。その是非はともかく、他にどんなやりかたができるのか調べてみたものです。


↓ こんなクラスがあるとして

```php
class NewClass 
{
  public $val = "TEST\n";
  
  public function echo() { echo $this->val; }
  
  public static function print() { echo "PRINT\n"; }
}
```

いろんな使い方を試してみた。

```php

// ふつう
$new = new NewClass;
$new->echo(); // TEST

// スタティック ふつう
NewClass::print(); // PRINT

// スタティック インスタンスから呼び出す
$new->print(); // PRINT インスタンスメソッドに見えるけどスタティック
$new::print(); // PRINT

// スタティック 文字列
(NewClass::class)::print(); // PRINT
'NewClass'::print(); // PRINT
$class = "NewClass";
$class::print(); // PRINT

// new 文字列
$class = "NewClass";
$new = new $class;
$new->echo(); // TEST

// new 文字列
$class = NewClass::class;
$new = new $class;
$new->echo(); // TEST

// new 文字列ダイレクト ....NG 意外と通らない
$new = new "NewClass";  // Syntax Error

// new 文字列ダイレクト ....NG これも通らない（意味ないけど）
$new = new NewClass::class; // Syntax Error
$new = new (NewClass::class); // Syntax Error


// インスタンスからクラス名を取得して new
$class = get_class($new);
$new = new $class;
$new->echo(); // TEST

// 修正を加えたインスタンスを用意して
$new = new NewClass;
$new->val = "MOD\n\n";
$new->echo();  // MOD

// そのインスタンスから新しいインスタンス
$new = new $new;
$new->echo();  // TEST

// 定数
define('NEW_CLASS',NewClass::class);
echo NEW_CLASS; // New Class

NEW_CLASS::print(); // NG Syntax Error
$new = new NEW_CLASS; // NG Syntax Error

```

さらに関数を定義して

```php

function NewClassName()
{
    return "NewClass";
}

// 関数の返り値をダイレクトに指定
NewClassName()::print(); // PRINT 通った
$a = new NewClassName(); // NG class NewClassName not found
$a = new (NewClassName()); // NG Syntax Error
```

static強いなぁ。クラスメソッドならどうだ！

```php
class NewClass 
{
  public $val = "TEST\n";
  public function echo() { echo $this->val; }
  public static function print() { echo "PRINT\n"; }
  
  // 以下２つを追加
  public function getClass() { return "NewClass"; }
  // メンバ関数をダイレクトに指定（括弧もない）
  public function echo2() { echo $this->getClass()::print(); }
}

$a = new NewClass;
$a->echo2(); // PRINT 通った
```



# で

インスタンスから新しいインスタンスを作成したり（JavaScriptみたいだ）、文字列やインスタンスからスタティックが呼び出せるか、と思ったのがきっかけで、結論としては、コレでいいや、といった感じ。

```php
$new = new $old;

$new::print();
```

2つ目のスタティックが `$new->print()` じゃないのは、インスタンスメソッドに見えることと、$newが文字列`"NewClass"`だと動かないから。`::`だと文字列でも動くという…。
JavaScript(ES6/ES2015)でオブジェクトをコピーする時に注意すること

どうも、はぐっです・ω・♪ 

# JavaScript(ES6/ES2015)でオブジェクトをコピー」
 
もう、babelを利用してES6/ES2015でJavaScriptを書いている人もだいぶ増えて来たことかと思います。で、様々な場面でオブジェクトを扱うことが多くあるはずっ。
んで、コピーしたいなんてこともあるはずっ。
そんなとき、コピーの仕方はいくつかあると思いますが、ここでは二つのやり方を。 

## コピーの方法
### jQueryを利用してオブジェクトをコピー 
 
JavaScript界の大ベテラン、「jQuery」 
こいつに、オブジェクトをコピーする時に使えるメソッドが用意されています。 
(本来の目的はオブジェクトのマージだったり。) 
 
<strong>$.extend</strong> 
 
使い方は 
 
```javascript
let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};

let secondObj = $.extend(true, {}, firstObj);
```
 
はいっ、こぴー。 

引数はこちら。
 
```
第一引数　　　　　　　: ディープコピーかどうか(省略可)
第二引数　　　　　　　: マージのもととなるオブジェクト
第三引数以降　: マージするオブジェクト(いくつでも)
```
 
ん？ 
ディープコピー？ 
 
そう！ 
今回はここがポイントです！ 
 
<strong>ディープコピーとは</strong> 
  
まぁ、「とは」っていうほど定義が必要なものではなくて、 
 
deep:深い 
 
つまり、深いコピーをするか、浅いコピーをするか。 
下の階層まで再帰的にコピーするか。 
 
ここ、割と大事。 
 
### ES6/ES2015を利用してオブジェクトをコピー 
 
ES6/ES2015になって、 
待ってましたー！！！！ 
な機能が様々追加され、いろいろとはっぴーになったわけですが、 
 
その中の一つ。 
 
<strong>Object.assign</strong> 
 
こいつ。 
 
使い方は 
 
```javascript
let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};

let secondObj = Object.assign({}, firstObj);
```
 
はいっ、こぴー。 
 
```
第一引数　　　　　　　: マージのもととなるオブジェクト
第二引数以降　: マージするオブジェクト(いくつでも)
```
 
うむ。 
さっきのjQueryのextendと使い方自体はそうかわら・・・ 
 
<b>ディープは！？</b> 
 
そう、ここが違うのです。 
 
Object.assignは、シャローコピー(ディープコピーと違って浅いコピー)なのです！！ 
 
これね、困る時があるんですよ。 

### コピーの方法による違い
 
例えば 

```javascript
let firstObj = {
  a: 'a',
  b: {
    a: 'a',
    b: {
      a: 'a'
    }
  }
};
```
 
があったとしてですよ。 

### $.extendの場合 
 
```javascript
let secondObj = $.extend(true, {}, firstObj);

secondObj.b.a = 2;

console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2
```
 
この場合、出力は 
 
```
1: a
2: 2
```
 
となります。 
 
### Object.assignの場合 
 
```javascript
let secondObj = Object.assign({}, firstObj);

secondObj.b.a = 2;

console.log(firstObj.b.a); // 1
console.log(secondObj.b.a); // 2
```
 
この場合、出力は 
 
```
1: 2
2: 2
```
 
となります。 
 
ほらああああああああああ！！！ 
 
こういうところで違いがでてくるんですよ！ 
 
だから言ったじゃないですかあああ！ 
 
…こほん。 
 
つまりね、 
 
オブジェクトがプロパティとしてオブジェクトを持っている時、 

シャローコピー(Object.assign)だと同じ参照 
ディープコピー($.extend(true))だと別参照 

となるわけですね。 
 
 
みなさま、くれぐれもオブジェクトのコピーは慎重に。

ES6/ES2015のご利用は計画的に。
JavaScript(infinite-scroll)で無限スクロールの実装

どうも、はぐっです・ω・♪

# JavaScript(infinite-scroll.js)で無限スクロールを実装

Webサイトを制作していく中で、
同じ属性のコンテンツを多く提供することがあるかと思います。

## 多量コンテンツの提供はページネーション？
  
まぁページネーションやんなー
って、今までやったら全然何の迷いもなくなってた。
ここに関しては、お前が知らんかっただけやろ。みたいな話は…受け付けません←
  
でも果たしてこういうとき、ページネーションしか方法がないのだろうか？  
と、いや、あるよな、よくアプリとかで見るで。ってなって、
調べたら、すぐに。極めてすぐに見つかりました。

## 無限スクロールという方法
  
スクロールが閾値を超えたら、次の数件を表示。
また閾値を超えたら、次の数件を表示。表示！表示！
という形で、どんどん下へ下へ次のコンテンツを表示していくスタイル。
  
これも、同じ属性のコンテンツを多く提供する一つの方法であるかと思います。
  
これからは無限スクロールでいけばいいの？
どうですか？
そんな簡単な話ではなさそうですね！

## ページネーションと無限スクロールの使い分け
  
じゃあどういうときにページネーション使うねん？
どういうときに無限スクロール使うねん？
  
私は
  
次へ次へとコンテンツを送っていった時に
  
<b>一度見たコンテンツをもう一度見たい！と、後戻りする場合はページネーション</b>
  
<b>一度見たコンテンツはもう見ない！と、後戻りしない場合は無限スクロール</b>
  
これがユーザ的には嬉しいのではないかなって思います。
  
## infinite-scroll.jsで実装！

[https://github.com/metafizzy/infinite-scroll](https://github.com/metafizzy/infinite-scroll)
  
試しに書いてみる。
オプションはいっぱいあるわけやけど、とりあえず最低限使いそうなところだけおさえておく。

```javascript
$('#js-wrapper').infinitescroll({
  navSelector  : 'ナビゲーションのセレクタ',
  nextSelector : '次へ、を実現するタグのセレクタ',
  itemSelector : '追加する要素のセレクタ'
});
```

そうね。
スクロールしたらページネーションの「次へ」を叩くようになっているイメージ！
  
例えば

```html
<div id="js-wrapper" class="haguhoms">
  <ul class="haguhoms__list">
    <li class="haguhoms__item">
      ~~~~
    </li>
  </ul>
  <div class="pagination">
    <span class="pagination__page"></span>
    <span class="pagination__next">
      <a rel="next" href="~~">次へ</a>
    </span>
  </div>
</div>
```

っていうのがあったとしたら、

```javascript
$('#js-wrapper').infinitescroll({
  navSelector  : 'nav.pagination',
  nextSelector : 'nav.pagination a[rel=next]',
  itemSelector : '#js-wrapper li.haguhoms__item'
});
```

はい、きたー。
これで最低限動くようにはなったかな！
  
他にも

```javascript
loading: {
  img     : 'ローディング中に出す画像のパス',
  msgText : 'ローディング中に出す文章'
}
```
とか

```javascript
errorCallback: function() {
  // エラーもしくは最後の要素が読まれた時に呼ばれるコールバック
}
```
とか

```javascript
$('#js-wrapper').infinitescroll({

}, function(elements) {
  // 一回分が追加されるときに呼ばれるコールバック
  // ちなみにelementsには、要素一個ずつ呼ばれるのではなく、一回分の要素が一回ですべて入ってくる
});
```
とか
とにかくいろいろできます！

出す時にふわっと出したいとかアニメーションつけたいとかあったら、こういうところをカスタマイズしていくことになりそうですな〜
  
要所要所で最適な解を導き出すために、こういう選択肢は常に増やしていくことを心がけたいものですね！
文系だってためらわずプログラミングをやろう

最近プログラミングを始めた文系大学生です。始めたばかりで何の知識もないため、自分と同じように文系だけどプログラミングを始めようかと悩んでいる人の背中を少しでも押せたらと思い書いています。
自分がプログラミングを始めた際、周りの人にそのことを言うと必ず「文系なのにやったって意味無いでしょ？」と言われました。確かに今、自分が大学で勉強している内容には一切寄与しないでしょう。それでも自分が始めた理由はただひとつ、「面白そう」だからです。ただただ「面白そう」だから。興味を持った発端はブロックチェーンでしたが、プログラミングの勉強を始めると、身の回りには膨大な数のモノ、サービスにプログラミングの技術が活かされていることに気付かされます。これだけ日常生活にプログラミングが溢れている今、「文系だから」という理由でプログラミング学習を鼻から諦めるのはもったいないと思います。文系学生であっても、プログラミングに少しでも興味を持ったら、学習を始めてみるべきです！　すぐ役に立つかどうかなんていう目先の損得勘定に惑わされず、今すぐにでも始めましょう。自分の興味に忠実になれば、新しい世界が見えるはずです。　思い立ったが吉日です。
ヨーロッパ、スウェーデンのストックホルムへ海外転職・海外移住する方法

はじめまして。
2018年10月からスウェーデンのストックホルムで、
モバイルゲーム会社で、Senior Backend Engineerとして働く予定のエンジニア Keです。

~~海外転勤ではなく~~、
__海外転職__を今後目指す方のために、
私の経験をこの場でシェアしていきたいと思います。

# 自己紹介
- 1987年生まれ♂
- 2010年大学卒業
- 日本のモバイルゲーム会社でエンジニアとして8年間勤務
- 2014年頃から海外移住目指し始める
- 2018年10月にストックホルムへ妻と移住予定

# 海外転職の理由
- __世界中の人に楽しんでもらえる作品を作りたい__
- __家族の時間をしっかり確保しつつエンジニアとして働きたい__

# 今後のコンテンツ予定
- 海外転職体験記
- [英語で職務経歴書/Resumeの作り方](https://qiita.com/yusuke0913/items/98ba6c6e4df52c25bb94)
- エージェントとSkype面談
- カバーレターの作り方
- 一次面接編
- コーディングテスト編
- オンサイトインタビュー編
- 英語勉強方法編
- ストックホルム移住準備
- [スウェーデンの労働許可・ビザ](https://qiita.com/yusuke0913/items/3fa50e50a216f1eeb0be)

# 今気になるTech関連
- Golang
- MicroService Architecture
- GoogleAppEngine

# 好きなメディア
- [Medium](https://medium.com/)

最近は気になるTech関連記事は、英語の勉強も兼ねて、medium上で探してます。他によいメディアあったら教えてください！

# 質問
yusuke.social.ebisu@gmail.com まで
.htaccessでリダイレクト設定[www有無統一][http,https]

どうも、はぐっです・ω・♪

#「.htaccessでリダイレクトを楽に設定しちゃおう♪」  

##登場人物  
###IfModule
指定したモジュールが利用できる場合に中身を評価する。

###mod_rewrite.c
リダイレクトとかURLの書き換えをしてくれる。
愛称:もどりらいと。

###RewriteEngineディレクティブ
Rewrite機能のオン・オフを制御する。

###RewriteCondディレクティブ
Rewrite機能のトリガーとなる条件を指定する。

###RewriteRuleディレクティブ
書き換えるURLを指定する。


##記述方法

###www 有り・無し 統一方法
```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^hoge\.co\.jp
RewriteRule (.*) http://www.hoge.co.jp/$1 [R=301,L]
</IfModule>
```

はい、wwwきたー。

###httpをhttps化
```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</IfModule>
```

はい、httpsきたー。

ってな感じです。

で、実際の状況を考えて、
**「wwwに統一、かつhttps化」**
という状況の.htaccessの中身を載せちゃいます！

```
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTP_HOST} ^hoge\.co\.jp
RewriteRule (.*) http://www.hoge.co.jp/$1 [R=301,L]
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [R,L]
</IfModule>
```

覚えるにはめんどくさいけど、いつもやる作業をめもってみた。
件。
Dialogflow チュートリアルをActions on Google API v2 対応にする

## はじめに
軽くDialogflow を触ってみようとググったらGoogle 公式っぽいチュートリアルが見つかったので試してみたところ、Actions on Google でエラーになったので対応をメモしておきます。

試したチュートリアルはこちら。
[Dialogflow で初めてのアプリをビルドする](https://developers.google.com/actions/dialogflow/first-app?hl=ja)

※ 2018/07/10 時点の情報なので、チュートリアルページがアップデートされたらこの記事は不要になります。

## Dialogflow とは
Google のチャットボットフレームワーク、でいいのかな。昔はApi.ai という名前でした。Actions on Google やSlack などと連携して音声/テキストのユーザーインタフェースを作れます。

[Dialogflow](https://dialogflow.com/)

その他出てくるサービス名などはチュートリアルを実施する方なら説明不要と思うので、説明は省略。

## チュートリアルでエラー発生
順調に進めていたんですが、「フルフィルメントを構築する」のところでエラーが発生しました（Actions on Google で返事が戻らなかった）。フルフィルメント(Fulfillment) はWebhook でFirebase のFunctions を呼ぶところですね。

Firebase コンソールでログを確認すると次の行がありました。

```
Error: Dialogflow v2 is not currently supported
```

## 何が問題だったのか
ログにあるとおり、Dialogflow API がv1 からv2 にバージョンアップしていました。
Dialogflow のページにアクセスすると上部に警告表示されていたので「へー」と思って即[DISMISS]してたんですが、チュートリアルも対応未済でした。

![dialogflow-warn.png](https://qiita-image-store.s3.amazonaws.com/0/241491/66ee5a22-2da7-e69b-e3e8-2d8925ba6df9.png)

v1 からv2 へのマイグレーションについては、警告内の「Learn how to migrate your V1 agents [here](https://dialogflow.com/docs/reference/v1-v2-migration-guide)」のリンク先でもいいんですが、Actions on Google のドキュメントの方がv1 とv2 の対応コードも記載されていて分かりやすいので、こちらを参照すると良いと思います。

[Actions on Google Node.js Client Library Version 1 Migration Guide](https://developers.google.com/actions/reference/nodejs/lib-v1-migration)

## API v2 への対応コード
ひとまずチュートリアルを動かしたところなのでv2 での変更点は本記事では解説しませんが、対応したチュートリアルのコードを載せておきます。

```JavaScript
const functions = require('firebase-functions');
const { dialogflow } = require('actions-on-google');

// a. the action name from the make_name Dialogflow intent
const NAME_ACTION = 'make_name';

// b. the parameters that are parsed from the make_name intent 
const COLOR_ARGUMENT = 'color';
const NUMBER_ARGUMENT = 'number';

const app = dialogflow();

// c. The function that generates the silly name
app.intent(NAME_ACTION, (conv => {
  let number = conv.parameters[NUMBER_ARGUMENT];
  let color = conv.parameters[COLOR_ARGUMENT];
  conv.close('Alright, your silly name is ' +
             color + ' ' + number +
             '! I hope you like it. See you next time.');
}));

exports.sillyNameMaker = functions.https.onRequest(app);
```

## まとめ
チュートリアル等の日本語訳はありがたいんですが、最新への追従が遅れていたりするので注意が必要ですね。(チュートリアル最終更新日が2018/3/20、API v2への移行が2018/4/16……つらい)（チュートリアルがアップデートされたらこの記事は不要になります）
ファイルの中に記述されている１行目を取得し、画面に表示させたい

Macでワードで、
１行目
２行目
３行目
と文字を打ち、txtにして保存しました。(ファイル名:phptanaka)
次にviエディタで下記を打ち込みました。 


```
<?php
  
$fp= fopen("phptanaka","r");

$lines = fgets($fp);

fclose($fp);

$hoge = file("phptanaka");
print $hoge[0];

?>
```

```
Warning: fopen(phptanaka): failed to open stream: No such file or directory in /Users/tanakaakio/aaa.php on line 3

Warning: fgets() expects parameter 1 to be resource, boolean given in /Users/tanakaakio/aaa.php on line 5

Warning: fclose() expects parameter 1 to be resource, boolean given in /Users/tanakaakio/aaa.php on line 7

Warning: file(phptanaka): failed to open stream: No such file or directory in /Users/tanakaakio/aaa.php on line 9
```

素人すぎてエラー内容を見ても解決のすべがわかりません。何が間違っているかご助言頂けると幸いです。宜しくお願いします。
WordPressでカスタムフィールドの条件を指定してカスタム投稿タイプの投稿を取得してみる

どうも、はぐっです・ω・♪

#WorePressでカスタム投稿タイプを扱う

**「WordPressでカスタムフィールドの条件を指定してカスタム投稿タイプの投稿を取得するにはどうしたらええんや」**
っていう壁にぶち当たった話をします。

さぁ。

どうやって取んねん。

##魔法の言葉、get_posts

get_posts、なんてわかりやすい響き。そのまんま、投稿をげっとー。

今回の登場人物

```php
$args      : 取得条件
$post_type : 取得したいカスタム投稿タイプ
$key       : 条件として指定するカスタムフィールドのフィールド名(キー)
$value     : 条件として指定するカスタムフィールドの値
$posts     : 取得した投稿
```

### 条件として指定するカスタムフィールドが一つの場合

```php
$args = array(
  'numberposts' => 5, // 取得数
  'post_type'   => $post_type,
  'meta_key'    => $key,
  'meta_value'  => $value
);

$posts = get_posts($args);
```

はいげっとー。

### 条件として指定するカスタムフィールドが複数の場合

```php
$key1   : 条件として指定するカスタムフィールドのフィールド名1(キー)
$key2   : 条件として指定するカスタムフィールドのフィールド名2(キー)
$value1 : 条件として指定するカスタムフィールドの値1
$value2 : 条件として指定するカスタムフィールドの値2
```

```php
$args = array(
  'numberposts' => 5, // 取得数
  'post_type'   => $post_type,
  'meta_query'  => array(
    array(
      'key'   => $key1,
      'value' => $value1
    ),
    array(
      'key'   => $key2,
      'value' => $value2
    )
  )
);

$posts = get_posts($args);
```
 

はいげっとー。

ってな感じで、カスタムフィールドの条件を指定してカスタム投稿タイプの投稿を取得できました。

カスタム投稿タイプは、WordPressでなにかしらを作ろうとした時、かなりよく使う機能なので、今回取り上げたget_postsを使うときはかなり訪れるかと思います。

 

ちなみに、

```php
$args = array(
  'order' => 'DESC'
);
```

で、降順に取得したりと、get_postsには様々な装備(オプション)をつけることができます。
詳細はWE…公式サイトで。
自動テストの意義について考える

# はじめに

自動テストに関しては、賛否両論あると思います。
そんな中で、少しでも自動テストを書くようにチームの意識を変えていくには？という部分も含めて考えてみました。
ただ「必要でしょ！」というだけでは平行線なままなので、「否定派」「肯定派」のそれぞれが何を大事にしているのか？という部分も含めて整理してみました。

自動テストの導入を検討している方の助けに少しでもなればと思ってます。

私は、現在RSpecでの自動テストを導入しているプロジェクトと、自動テストを導入していないプロジェクトを掛け持ちしてます。

# 議題

0. なぜ否定派と肯定派が現れるのか
1. 必要性について
2. どこまで書くのか
3. 書くときに気をつけたいこと

# なぜ否定派と肯定派が現れるのか

## 否定派の意見

テストコードを書くことよにって下記が"失われる"

- 開発スピード
- 仕様変更対応へのコスト
  - 仕様変更があるたびに、テストコードも変更しないといけないから

つまるところ、『開発効率』が落ちると考えられていることが多い

## 肯定派の意見

テストコードを書くことによって下記が"得られる"

- 品質
- 影響範囲調査コストの軽減
  - １回テストを回せば全部わかるでしょ？

## なぜ平行線なのか

見ている「時間」と「結果」が違う

- 否定派
  - 「今」に重きを置いて議論している
  - 「失うこと」に重きを置いて議論している
- 肯定派
  - 「未来」に重きをおいて議論している
  - 「得られること」に重きを置いて議論している

## まずは…

同じ「時間」を見て話をすることが大事

- 「今」を見る
  - 自動テストを書くことのメリットは？
      - プログラム設計の妥当性検証
      - テストがかけないプログラムは、十中八九プログラムとして破綻している
  - 自動テストを書くことのデメリットは？
      - テストを書いている時間分、他の開発ができない

-  「未来」を見る
  - 自動テストを書くことのメリットは？
      - リファクタリングを積極的に行える
          - 正しい挙動が証明されているから
          - リファクタリング＝動きを変えずにコードを綺麗にすること（動きが少しでも変わるものはもはや「機能追加」）
  - 自動テストを書くことのデメリットは？
      - 大きな仕様変更があった場合に、テストを書き直す工数が発生する

# 必要性について

上記の内容から、プロジェクトにとって必要かどうかを判断すればいい。
ただ、個人的には上記の内容をみて「不要」と判断する人はそういないと思う。
（すでに「必要」と思っている人間なので、メリットの方がデメリットより強くなってる感はありますが）

個人的には「自動テストは必要」と考えてます。

## なぜ必要なのか

- 「今」コードの妥当性を確認できる
    - テストコードを書くことで、「テストが書きづらい部分」を知ることができる。
    - 大抵の場合、そういう部分にこそ、「バグ」の芽が潜んでいる。
    - 従来であれば、プログラム稼働後しばらくたって気づく様な「臭い」ポイントに、稼働前の実装時点で気づくことができるのは大きな収穫。

- 「今」かけるコストに以上の結果を、「未来」に得られる
    - 特に`リファクタリングを積極的に行える`というのは、長く運用・保守を続けていくシステムにとっては何よりも重要な要素
    - １年前のベストプラクティスが、１年後もそのままベストプラクティスとして通用するようなケースは少ない。
    - そのため、`いかにリファクタリングをしやすくしておくか`は、先々抱える技術的な負債を返却する機会を残しておくのに等しい。

# どこまで書くのか

目的を明確にしてスタートしないと、「とりあえず全部書く」状態になってしまう。
正直、これではいくらコストをかけてもキリがないので、

- 自動テストでテストすること
- 自動テストでテストしないこと

をしっかり決めてからスタートするのが吉。
「自動テストで全てのテストを行おう」という思いを捨てることが一番大事だと思う。

まずは、プロジェクトとして「自動テストを行うことで何を得たいのか」ということを明確にすれば、自ずと「どんなテストを書く必要があるのか」ということが決まってくると思う。

## 例) 将来のリファクタリングを楽に確実に実行したい場合
- テストとして書いておくべき範囲
    - 各クラスが公開しているインターフェース（public / protectedメソッド）に関するブラックボックステスト
- 必ずしも書く必要のないテスト
    - 各クラスが公開していないインターフェース（privateメソッド）に関するテスト

上記の様に、「何を達成したいのか」というものをベースに「どこまで書くか」を決めていくのが一番いいのではないかと思う。

# 書くときに気をつけたいこと
自動テストもプログラミング。
従って、そこには一定の「ルール」が存在してしかるべき。

「ルール」を持ち込んだ方が良いと考える部分

- 構造を合わせる
- 表現を合わせる
- 共通Moduleのテストに気をつける

## 構造を合わせる

チームメンバーAとBが同じクラスに対するテストを書いたときに、「構造」が違うことがない様に注意する必要がある。

RSpecでは`describe` `context` `it / example`などで「構造」を表現していくため、プロジェクトとして、利用シーンの統一は必須事項。

## 表現を合わせる

1件1件のテストケースが、そのまま「テスト仕様書」「内部設計書」となることを考慮して、「実際のテストコードを読まなくても内容が理解できる」レベルで表現を統一するべき。

## 共通Moduleのテストに気をつける

共通モジュールを利用しているそれぞれのプログラムで、同じテストを書かない様にする
共通モジュールに変更があった場合、利用側は「テストコードが変更されていないがテストが失敗する」という結果になるようにテストを書くべき。

# おわりに

自動テストの実施に関して、思う部分を書いてみました。
多くのプロジェクトですでに利用されている技術ではあると思いますが、改めて整理してみることで見えてくる部分もあるかなと思います。

明確な答えがないからこそ、「プロジェクトとしての答え」を明確にしておく必要があると思っています。
Laravel で PHPUnit を使うには

# Laravel で PHPUnit 

## 起動編

前提
Laravel5.5 利用

- まずは使ってみる

「vendor/bin/phpunit」を実行
(デフォルトで)登録されているテストコードを実行するようになっている

```
$ cd laravel
$ ./vendor/bin/phpunit 
You need to set up the project dependencies using Composer:

    composer install

You can learn all about Composer on https://getcomposer.org/.
```
<font color="Red">エラー?</font>

どうやら vendor以下を削除して、composer install をする必要があるようです
僕は vendor/bin のみ削除してやり直したらうまくいきました。

```
$ rm -rf vendor/bin
$ composer install
～
Package manifest generated successfully.
```

## サンプルテスト編

もう一度、「vendor/bin/phpunit」を実行

```
$ cd laravel
$ ./vendor/bin/phpunit
PHPUnit 6.5.7 by Sebastian Bergmann and contributors.

F.                    2 / 2 (100%)

Time: 317 ms, Memory: 14.00MB

There was 1 failure:

1) Tests\Feature\ExampleTest::testBasicTest
Expected status code 200 but received 302.
Failed asserting that false is true.

/～/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestResponse.php:78
/～/tests/Feature/ExampleTest.php:19

FAILURES!
Tests: 2, Assertions: 2, Failures: 1.
```
<font color="Red">エラー2</font>

このデフォルトのテストは、真っ白なインストールしたての laravel 用のテストであり、
僕のようにある程度構築し終わってるとこのようにエラーにされます。
結論からいうと、認証系の処理を入れていたため「/」のときにリダイレクトされてステータスコードが302になっていたからということでした。
なので、ソースコードを以下のように変更します。

```tests/Feature/ExampleTest.php
class ExampleTest extends TestCase
{
    /**
     * A basic test example.
     *
     * @return void
     */
    public function testBasicTest()
    {
        $response = $this->get('/');

 -      $response->assertStatus(200);
 +      $response->assertStatus(302);  // ステータスコードを変更
    }
}
```

僕のような凡ミスはさておき、基本は storage\logs\laravel.log に出力されるそうなので、
そちらを確認してうまいこと解決策を見出してください。

成功しました。

```
$ ./vendor/bin/phpunit 
PHPUnit 6.5.7 by Sebastian Bergmann and contributors.

..                    2 / 2 (100%)

Time: 284 ms, Memory: 14.00MB

OK (2 tests, 2 assertions)
```

## 実行編

* テスト全実行

```
./vendor/bin/phpunit
```

* テスト単体実行

```
./vendor/bin/phpunit tests/Feature/LoginTest.php
```

* テスト作成

```
php artisan make:test LoginTest
php artisan make:test UserTest --unit   # unit方のテストをするときはこちら
```
selectタグで選択されたoptionのカスタム属性を取得する方法

プルダウンから選択された属性（カスタムデータ属性）をinnerHTMLへ出力するサンプル

jQueryでのやり方はたくさんあるけど、プレーンなjsではサンプルがなかったので。


```html:select.js

<table border="1">
<tr>
  <td>hoge区分</td>
  <td>
  <select id="sel" 
       onchange="document.getElementById('text1').textContent = this.options[this.selectedIndex].dataset.view">
    <option data-view=""></option>
    <option data-view="aaa" value="1">1 AAA</option>
    <option data-view="bbb" value="2">2 BBB</option>
    <option data-view="ccc" value="3">3 CCC</option>
    </select>
  </td>
  <td id="text1" >hogehoge</td>
</tr>
</table>
```

単純にvalue値を取得するケース。
onchangeイベントを以下の記述に変更。

```js:basic.js
document.getElementById('text1').value = this.value;

```
Ubuntu16.04にPHP5.6を入れる

## 概要
昔、Ubuntu16.04（WSL環境）に何かをしてPHP7からダウングレードした記憶があったのですが、具体的に何をしたのか覚えていなかったので、簡単にメモを起こしました。

## 前準備
調べた手順にならって作業をしました。

```bash
$ sudo add-apt-repository ppa:ondrej/php
```

ここで以下のようなエラーが出ました。

```bash
Cannot add PPA: 'ppa:~ondrej/ubuntu/php'.
ERROR: '~ondrej' user or team does not exist.
```

1つ1つやりましたが、自分の環境では、以下すべて終えたところで、` $ sudo add-apt-repository ppa:ondrej/php`が初めて上手くいきました。

```bash
$ sudo apt remove --purge ca-certificates
$ sudo apt autoremove
$ sudo apt install ca-certificates
$ sudo apt install software-properties-common
```

上記を行って、再度実行し、updateします。

```bash
$ sudo add-apt-repository ppa:ondrej/php
$ sudo apt-get update
```

## 目的のPHPのインストール
目的のPHPのインストールをします。

```bash
$ sudo apt install php5.6 php7.0
```

apache2を入れていて、こっちでも利用する予定なので、以下を追加でしました。

```bash
$ sudo apt install libapache2-mod-php5.6 libapache2-mod-php7.0
```

## 切替え
目的のバージョンに切り替えます。

```bash
$ sudo a2enmod php5.6
$ sudo apachectl restart
$ sudo update-alternatives --set php /usr/bin/php5.6
```
PostgreSQL ソート インデックス

# PostgreSQL ソート インデックス

- 最新順(desc)でソートするクエリの場合、応答時間高速化の効果が期待できる

## Requirements
psql (9.3.2)

## インデックス作成
```
CREATE INDEX idx_hoge_code_desc ON hoge(code DESC);
```
- hoge に対して、`テーブルロック` が発生するので、サービス停止中等に実行するのがベター
- `レコードの多いテーブル` の場合、実行時間が長時間かかる可能性があるので、事前に同じデータのDBを同等スペックの別サーバ等に準備して、時間を予測しておく。キャッシュは恐らく実行時間には影響しなさそう。
- 途中で止めたい場合は `Ctrl + c` でキャンセル可能、恐らく問題ない

## （`何かあって`）インデックス作成 削除する場合
```
DROP index idx_hoge_code_desc;
```


## 確認
```
# \d hoge
                                        Table "public.hoge"
     Column     |            Type             |                        Modifiers
----------------+-----------------------------+---------------------------------------------------------
 code           | integer                     | not null default nextval('hoge_code_seq'::regclass)
 …
Indexes:
    "idx_hoge_code_desc" btree (code DESC)
```


```
# \d idx_hoge_code_desc
Index "public.idx_hoge_code_desc"
     Column     |  Type   |   Definition
----------------+---------+----------------
 code           | integer | code
 …
btree, for table "public.hoge"
```
- `DESC` の情報が表示されない… 確認する方法知ってる方いらっしゃったら教えてください


## インデックス前後 統計情報 比較

- インデックス作成 前

```
# explain analyze select * from hoge where order by code desc limit 50;
                                                                           QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.44..2146.45 rows=50 width=44) (actual time=6797.790..6822.734 rows=50 loops=1)
   ->  Index Scan Backward using hoge_pkey on hoge  (cost=0.44..1418472.53 rows=33049 width=44) (actual time=6797.787..6822.728 rows=50 loops=1)
   …
 Total runtime: 6822.785 ms
```


- インデックス作成 後

```
# explain analyze select * from hoge where order by code desc limit 50;
                                                                           QUERY PLAN
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=0.56..44.30 rows=50 width=44) (actual time=0.089..0.221 rows=50 loops=1)
   ->  Index Scan using idx_hoge_code_desc on hoge  (cost=0.56..28818.94 rows=32950 width=44) (actual time=0.086..0.206 rows=50 loops=1)
 Total runtime: 0.279 ms
```

`早なった`
.NET Core逆引きメモ

必要に迫られた.NET Coreの逆引きメモです。

# `dotnet tool install`で`~\5.0.100\NuGet.targets(131,5): error`が出る場合の対処方法

`--ignore-failed-sources`のオプションを付ける。

```powershell
dotnet tool install -g TestTool-3.1 --ignore-failed-sources
```



# dotnet-aspnet-codegenerator no executable found

`aspnet-codegenerator`を実行すると`そんなコマンド有りません。`とエラーが出るのでメモ。

1. 実行したいプロジェクトの`.csproj`をテキストエディタで開く。
2. `*.csproj`に`DotNetCliToolReference `を追記
3. `Version="x.x.x"`の部分は`パッケージマネージャコンソール`で`nuget list Microsoft.VisualStudio.Web.CodeGeneration.Tools`を実行して確認。

```:*.csproj
<ItemGroup>
    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="x.x.x" />
</ItemGroup>
```
**参考**
[.ASP.NET Core MVC アプリへのモデルの追加](https://docs.microsoft.com/ja-jp/aspnet/core/tutorials/first-mvc-app-mac/adding-model?view=aspnetcore-2.1)
CentOS7構築手順

動作確認のためにCentOS7を構築する際、毎回インターネットで検索しながら環境構築していたので、自分の備忘録として記載。

環境は以下

- Windows10 Enterprise
 - プロセッサ：Corei7 6600U @ 2.60GHz 2.81GHz
 - 実装メモリ(RAM)：8.00GB
 - OS種：64bit
- VMware(R) Workstation 12 Player
 - 12.5.7 build-5813279
- CentOS7

#インストール
詳細は省略。
環境に合わせて仮想マシンを設定。
サウンドカード、フロッピー、プリンターなどは使わないのでこの時点で削除。
インターネットに到達性を持たせるため、ネットワークはNATを選択。
※Minimalインストールとする。

#インストール完了～SSH接続
コンソール画面ではいろいろめんどくさいので、ターミナルソフトからSSHでログイン。

#net-toolsをインストール
CentOS7では、初期状態だと"ifconfig"や"netstat"などのコマンドが入っていないのでインストールする。
※非推奨コマンドになったので、今後なくなる可能性あり。

```
yum install net-tools
```

※補足
よく使うコマンドの置き換わりは下記

``ifconfig`` = ``ip addr``
``arp`` = ``ip nei``
``route`` = ``ip route``
``netstat`` = ``ss``

#パッケージを最新にアップデート
パッケージをすべて最新に

```
yum update
```


#selinuxの無効化
検証目的のため、動作に影響を与えないように無効化

```
vi /etc/selinux/config
```

```ruby:/etc/selinux/config
SELINUX=disabled
```
`SELINUX=enforcing`を`disabled`に変更する

編集後、サーバを再起動

確認コマンド

```
# getenforce
Disabled
```
'Disabled'と応答があればOK

#bash-completionをインストール
systemctlコマンドでtab補完ができるようにbash-completionをインストール

```
yum install bash-completion
```

#時刻同期
デフォルトだと時刻同期していないのでchronyをインストール
※chrony...CentOS7から導入されたntp兼サーバ

```
yum install chrony.x86_64
```

chronyを起動し状況を確認

```
systemctl start chronyd
systemctl status chronyd
```
時刻同期先を設定

```
vi /etc/chrony.conf
```

```ruby:/etc/chrony.conf
#server 0.CentOS.pool.ntp.org iburst
#server 1.CentOS.pool.ntp.org iburst
#server 2.CentOS.pool.ntp.org iburst
#server 3.CentOS.pool.ntp.org iburst
server ntp2.jst.mfeed.ad.jp iburst
```
※インターネットの時刻同期サーバを記載

サービス再起動

```
systemctl restart chronyd
```

自動起動設定

```
systemctl enable chronyd
```


時刻同期確認

```
chronyc sources
timedatectl
```


#locateコマンドのインストール
ファイル検索用にlocateコマンドをインストール

```
yum install mlocate
updatedb
```

#Python3.6のインストール
IUSというリポジトリを追加

```
yum install -y https://centos7.iuscommunity.org/ius-release.rpm
```

python3のバージョンを検索

```
yum search python35
yum search python36
```

最新の3.x系は3.6なので3.6をインストール

```
yum install python36u python36u-libs python36u-devel python36u-pip
yum install python-pip #python2
```
※必要そうなものを入れる


#Gitコマンドのインストール

```
yum install git
yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel perl-ExtUtils-MakeMaker
```


思いついたら追記
Images API にはストレージオブジェクトの OWNER 権限が必要

## Images API

Google App Engine では Images API という、とても便利な API が提供されています。

https://cloud.google.com/appengine/docs/standard/go/images/

これは Google Cloud Storage に保存された画像を、フォーマットやサイズを指定して配信してくれる画像プロキシのようなものです。

（日本だと、さくら＆pixiv で ImageFlux というサービスが同じような機能を提供しています）

## App Engine

App Engine から Google Cloud Storage に画像を保存して Images API を呼び出す場合は特に気にすることはありません。App Engine を作成すると、アプリ名（example.appspot.com）と同じ名前のバケットが Google Cloud Storage に作成され、そこに保存し、そこから Images API を使うだけです。

## 外からファイルをアップロードした場合

App Engine の外（ローカルや、別のマシン）からファイルをアップロードする場合は、適切な権限を設定する必要があります。

画像が READ 可能なだけでは Images API の呼び出しが失敗するので、オブジェクトの OWNER 権限を App Engine に対して付与します。App Engine はバケットに対して OWNER 権限を持っていますが、オブジェクトごとの ACL が優先になっている（外部からアップロードした場合、そのストレージオブジェクトの OWNER はアップロード者になる）ので、対象オブジェクトへの OWNER 権限は別途付与する必要があるようです。

App Engine のサービスアカウント "App Engine default service account" が `example@appspot.gserviceaccount.com` のような名前で存在していると思いますので、そのアカウントに対して OWNER 権限を付与します。

```
gsutil acl ch -u example@appspot.gserviceaccount.com:OWNER gs://example.appspot.com/your-image.jpg
```

これで、対象オブジェクトに対して Images API を使うことができます。
intellij syntax highlightがうまく機能しなくなった時

＃　ある日突然intellijの syntax highlightが聞かなくなった

そういう時は右下のバケツマークを押してsyntaxをhighlightするよう設定しなおせば良い。





<img width="377" alt="スクリーンショット 2018-07-10 10.50.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/236412/00407164-d79b-9a96-092f-32d8d7593ddd.png">
既存VagrantのVirtualBox（vbox）フォルダを変更する

Cドライブが逼迫・・・！
これを恐れて、予め`.vagrant.d`をDドライブに設定しておいたんだけど、なんでかな？と調べたら、どうもVirtualBoxのvboxが容量を食っているようでした。
というわけで、Dドライブに場所を移行したのでそのまとめ。

# 既存Vagrantのboxファイル作成
ホスト（Windows、Mac等）の`vagrant init`済フォルダにて、既存のVagrantをbox化します。
時間がかかりますが、気長に待ちましょう。

```bash
$ vagrant halt            #vagrant 実行中の場合
$ vagrant package
==> default: Exporting VM...
==> default: Compressing package to: D:/centos/package.box
```

# VirtualBoxの仮想マシンフォルダ変更
任意の場所（Dドライブ等）にVirtualBox用のフォルダを作成しておきます。
VirtualBoxマネージャーを開き、**ファイル** -> **環境設定** -> **一般** -> **デフォルトの仮想マシンフォルダー**を、↑のパスに変更。
基本はこれだけで問題ないはずですが、`vagrant up`時に元のフォルダにvboxを作ろうとしてしまったので、コマンドでも設定をしました。

```bash:Windowsの場合
$ "%VBOX_MSI_INSTALL_PATH%\VBoxManage.exe" setproperty machinefolder "D:\VirtualBox VMs"        # 作成したフォルダ
```

# 新Vagrant環境作成
念のため、既存環境はそのままに新しく作り直します。
Vagrant用のフォルダを作り、上記で作ったboxも同じ場所にコピーしてしまいましょう。
フォルダに移動し、boxをaddします。

```bash
$ vagrant box add centos centos.box
==> box: Box file was not detected as metadata. Adding it directly...
==> box: Adding box 'centos' (v0) for provider:
    box: Unpacking necessary files from: file://D:/centos2/centos.box
    box: Progress: 100% (Rate: 105M/s, Estimated time remaining: --:--:--)
==> box: Successfully added box 'centos' (v0) for 'virtualbox'!
```

さて、通常はここで`vagrant init`を実行しますが、色々設定済みのVagrantfileをもう一度書き直すのは面倒くさい。
ということで、既存環境からVagrantfileをコピーしてきます。
既存Vagrantとbox名が変わっている場合は、box設定の変更が必要です。

```ini:Vagrantfile
config.vm.box = "centos.box"        # ↑で作成したbox名
```

`vagrant up` すると、新しく設定した仮想マシンフォルダにvboxが作成されます。

```
$ vagrant up
```

動作に問題がなければ、古いVirtualBox環境のファイルを削除してしまいましょう。
z88dkの始め方

z88dkファイルをダウンロードする。
自分の場合
http://nightly.z88dk.org/
から z88dk-win32-latest.zip をダウンロードした。

圧縮ファイルを解凍し、適当なディレクトリに配置する。
例）C:\etc\z88dk

開発用ディレクトリを用意する。
例）C:\Projects\z88dk

開発用バッチファイルを用意する。

```dev.bat
@echo off
path %path%;C:\etc\z88dk\bin
set ZCCCFG=C:\etc\z88dk\lib\config
cmd
```

- サンプルプログラム

```hello.c
#include <stdio.h>

void main()
{
	printf("hello, world");
}
```

コンパイル
`zcc +msx -lndos -create-app hello.c`
a.casファイルが作られる。

WebMSX http://webmsx.org/ を起動する。
a.casファイルをCassetteにドロップする。
`bload"cas:",r`
と入力する。
「"」を入力しようとして@など出たときは、右下の歯車アイコンから「Select Machine」→「MSX2+ Japan (NTSC)」を選択する。
![WMSX Screen (3).png](https://qiita-image-store.s3.amazonaws.com/0/257554/a68b8aff-b85f-b632-b147-e1e353cc7010.png)

`-bn`オプションを付けてコンパイルするとテープ自動読み込みしてもSkipされなくなる。詳しくは
[z88dkのMSXテープ自動読み込み](https://qiita.com/Stosstruppe/items/4d5dfed362b6dbe7ffe9)
bitcoin core rpc/ getnewaddressでp2pkhアドレスを得るには

# 環境
bitcoind v0.16.99.0-87a9d03c0

# 困った
bitcoin core rpcで`getnewaddress`すると

```bash:bash
$ bitcoin-cli -regtest getnewaddress
2N1Xx8taTNrm2RLxdeHMHT5fqgPJ219FWti
```
のように2で始まるアドレス、すなわち(テストネットの)p2SHのアドレスを教えてくれる[^1]。
でも、m,nではじまるP2PKHアドレスがほしい...。

# どうして？
0.16からsegwitアドレスがデフォルトに[^2]。
> Bitcoin Core 0.16.0 introduces full support for segwit in the wallet and user interfaces. A new -addresstype argument has been added, which supports legacy, p2sh-segwit (default), and bech32 addresses.

segwitアドレスを取得する`addwitnessaddress`というコマンドがあったらしいが、それが廃止になり、`getnewaddress`の引数でアドレスタイプを指定できるようになった[^3]。  

>  wallet RPC addwitnessaddress was deprecated and will be removed in version 0.17, set the address_type argument of getnewaddress, or option -addresstype=[bech32|p2sh-segwit] instead.


# どうする？
`getnewaddress`の引数はlabelとaddress_type。
address_typeに'legacy'を指定することで、P2PKHアドレスを得ることができる[^4]。

```bash:bash
$ bitcoin-cli getnewaddress "" "legacy"
moNuxPWGrK96NQwHugF6NcYpoXJrXMouz8
```

# 参考
[^1]: [list of address prefix](https://en.bitcoin.it/wiki/List_of_address_prefixes)
[^2]: [0.16 release note/ segwit-wallet](https://github.com/bitcoin/bitcoin/blob/d3f4dd313e5fe58903caf2f4d04827e7f7944e17/doc/release-notes/release-notes-0.16.0.md#segwit-wallet)
[^3]: [0.16 release note/ RPC changes](https://github.com/bitcoin/bitcoin/blob/d3f4dd313e5fe58903caf2f4d04827e7f7944e17/doc/release-notes/release-notes-0.16.0.md#low-level-changes)
[^4]: [rpcwallet.cpp](https://github.com/bitcoin/bitcoin/blob/3f0f39415bd7dfcb246926dbb0b29f98d6f19da5/src/wallet/rpcwallet.cpp#L135)
【SpatiaLite】MULTIPOINTを含むGEOMETRYCOLLECTIONを生成するとPOINTに分解される

以下のように、POINT, MULTIPOINTを要素とするGEOMETRYCOLLECTIONのWKTからジオメトリを生成する。

```sql
SELECT
	AsText(gc.gc)
FROM
(
	SELECT
		GeomFromText(
			'GEOMETRYCOLLECTION(' ||
				'MULTIPOINT(2 2, 1 1)' ||
				', POINT(3 3)' ||
			')'
		) AS gc
) AS gc
```

すると、以下に示す実行結果のように、MULTIPOINTの各点がPOINTに分解されたGEOMETRYCOLLECTIONが得られる。

```
GEOMETRYCOLLECTION(POINT(2 2), POINT(1 1), POINT(3 3))
```
脱VirtualBox || Windows Subsystem for Linuxを入れてみた(インストール)

# 忙しい人向け(かなりざっくりした手順です)

## :construction: VirtualBox、使いやすかったのにな

### VirtualBox・・・
***
本当に使いやすかったですね、VirtualBox
でも、ある日突然VT-Xが云々とか、働きたくないみたいなこと言ったので除外します
Windows UpdateでVT-Xまわり、およびHyper-vあたりで何かが起きたっぽいけど、
全然調査する気になれませんでしたｗ

一応1時間くらいはやったけど、時間の無駄かな、と

### VirtualBoxで入っていた環境
***
SolydX

### Windows環境
***
エディション：Windows 10 Enterprise
バージョン：1703
実装RAM：24GB

今回ここにインスコしていきます

```
ここで、
もしかしたらバージョンを1703から1803に上げたら直るかも、と思いましたが
Windows Subsystem for Linuxを使ういい機会だと思ったので、思いとどまりました
さようなら、Windows 10 April 2018 Update
```

## インストール開始
### まずはWindows側を受け入れ態勢に
1. スタートメニュから`アプリと機能`を選択 
2. `プログラムと機能`を選択
3. `Windowsの機能の有効化または無効化`を選択
4. `Windows Subsystem for Linux(Beta)`にチェックを入れる
5. 上記設定反映のため再起動
6. スタートメニュから`設定`から`更新とセキュリティ`、`開発者向け`と進み、`開発者モード`にチェックを入れる
7. 右記コマンド実行`$ lxrun /uninstall`で古いWindows Sybsystem for Linuxを削除 ※ある場合
8. PowerShellを管理者で起動して、右記コマンド実行`$ bash`して、`Microsoft Store`から`Ubuntu`を入手
9. 対話に従って、ロケールの設定とユーザ/パスワードの設定を行う
10. Ubuntuのアップデートを行う`$ sudo apt-get update` `$ sudo apt-get upgrade`
11. GUI使いたい方はこちらを入れてください[WSLをGUIで使うためのVcXsrv](https://sourceforge.net/projects/vcxsrv/files/vcxsrv/) ` => vcxsrv-64.1.20.0.0.installer.exe`
12. VcXsrvを起動し常駐させておく
13. タスクバーのVcXsrvにカーソルを合わせると`host:0.0`で表示されれば常駐完了
14. PowerShellで`$ bash`実行後、`$ export DISPLAY=localhost:0.0`を実行
15. `$ xeyes &` でっかい目玉が画面に表示されれば成功
16. GUIをいれる`$ sudo apt install lxde`

### 今回のインストール作業で使ったコマンド
***
```
$ lxrun /uninstall /full

$ bash
上記で素直にインストールできない場合は、下記を試してみる
$ lxrun /uninstall /full
$ lxrun /install

$ sudo apt update && sudo apt upgrade -y
$ sudo apt install language-pack-ja
$ sudo update-locale LANG=ja_JP.UTF-8
$ sudo apt-get install git build-essential libssl-dev libreadline-dev zlib1g-dev x11-apps x11-utils x11-xserver-utils libsqlite3-dev nodejs fonts-ipafont libxml2-dev libxslt1-dev

$ export DISPLAY=localhost:0.0
 => ~/.bashrcに記述でもよい
$ xeyes &
$ sudo apt install lxde
$ sudo apt install lxsession-logout
$ lxpanel --profile LXDE &
$ sudo apt install fontconfig
```

### ついでに
***
```
atom インストール
$ sudo add-apt-repository ppa:webupd8team/atom
$ sudo apt-get update
$ sudo apt-get install atom
 => 動かない、時間の無駄でした
    というかそもそもWSLはVMではないので入れる意味を考えたら不要でした

git インストール
$ sudo apt-get install git
$ sudo apt-get update
$ git config --global user.email "xxxxxxx@gmail.com"
$ git config --global user.name "xxxxxxxx"
$ git config --global push.default simple
$ git config --global -l

nodebrew
$ curl -L git.io/nodebrew | perl - setup
```

github関連でいつも忘れるので
[Generating a new SSH key and adding it to the ssh-agent](https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/)
[Adding a new SSH key to your GitHub account](https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/)


### 感想
***
GUIを有効化したけど、結局GUIなんて使わないと気付く
PowerAppsで入力ボタンを作ってみた

#今回の投稿背景
来客受付の電子化は好評です。
実際はタブレットに表示しているのですが
入力には手書き入力IMEを使用しています。

バッテリが死んでいるSurface 2 RT（Windows 8.1 RT）と
Androidタブレットの両方で試していますが
やはり入力するとなると手書き認識に時間がかかってしまい
スムーズな登録とはちょっと言えません。

なので来訪が分かっているお客様には
予め予約番号を発行しておいて、それを入力させるってのが
一番スマートなんじゃないかなという妄想に駆られました

#とりあえずデモ
Twitterに動画を上げましたので、そちらを埋め込んでみました。
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr"><a href="https://twitter.com/hashtag/PowerApps?src=hash&amp;ref_src=twsrc%5Etfw">#PowerApps</a>　で<a href="https://twitter.com/hashtag/%E5%85%A5%E5%8A%9B%E3%83%9C%E3%82%BF%E3%83%B3?src=hash&amp;ref_src=twsrc%5Etfw">#入力ボタン</a><a href="https://twitter.com/hashtag/%E4%BD%9C%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F?src=hash&amp;ref_src=twsrc%5Etfw">#作ってみた</a><br>これでわざわざキーボード呼び出しをする必要もないから便利になるかも！<a href="https://twitter.com/hashtag/inputbutton?src=hash&amp;ref_src=twsrc%5Etfw">#inputbutton</a><a href="https://twitter.com/hashtag/button?src=hash&amp;ref_src=twsrc%5Etfw">#button</a> <a href="https://t.co/mQ8eZ0ZBqD">pic.twitter.com/mQ8eZ0ZBqD</a></p>&mdash; りなたむ@steed400 (@R_t_A_n_M) <a href="https://twitter.com/R_t_A_n_M/status/1016319755618168838?ref_src=twsrc%5Etfw">2018年7月9日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#作り方
##材料
ラベル・・・・・・・・ 1個（コンテキスト変数表示用）
ボタン・・・・・・・・11個（0～9の入力ボタン＋クリアボタン）
コンテキスト変数・・・ 1個

##手順
1. ラベルを1つ作ります。名前はTextboxとします。
2. TextboxのTextプロパティにVar1をセットします。
3. ボタンを1つ作ります。名前はPush1とします。
4. Push1のTextプロパティに1をセットします。
5. OnSelectプロパティに右の内容をセットします。`UpdateContext({Var1: Var1&Push1.Text})`
6. Push1を9個コピーし、Push2～0を作成します。それぞれのTextプロパティも2~0をそれぞれセットします。
7. ボタンを新しく一つ作ります。名前はCLEARとします。
8. Onselectプロパティに右の内容をセットします。 `UpdateContext({Var1: ""})`

##完成画面
![入力制御.png](https://qiita-image-store.s3.amazonaws.com/0/269159/9f6d79b5-8681-487c-1ff3-fca548a0dd3f.png)

##解説
変数についてはこちらのサイトを参考
https://docs.microsoft.com/ja-jp/powerapps/maker/canvas-apps/working-with-variables

ラベルはTextプロパティの内容を表示する機能なので
Textプロパティにコンテキスト変数のVar1を指定。
各ボタンには0~9まで番号をこれまたTextプロパティに指定していて、それがボタンの表示に使用されている。
`Push1.Text`　とすると、戻り値はPush1のTextプロパティの値（1）を返してくれるので
それをコンテキスト変数のVar1に代入しているという感じ。
Var1に代入されたら、それを表示するようにTextboxに宣言しているので、表示されるという仕組み。

ただ、さっきのリンク先サイトのように
変数に＋で新たな数値を入れると、加算扱いとなってしまう。
※Excelも一緒
なので、＆を使用することで文字列結合を行うことができる。

コンテキスト変数を使用したのは、この画面内のみで使用するため。
実際に使用するときも、検索用途しか使わないので。
アプリ内の共通変数として使いたいなら、グローバル変数とかコレクション変数を使うのかな


#まとめ
関数の使い方はほんとExcelにめっちゃ似てる。
変数の考え方がいくつかあるからちょっとその辺はよく整理しないと
実運用のときに苦労するかも


ちなみに、作成時間は試行錯誤含めて２０分ぐらいです。
むしろこの投稿をするのに時間かかってるわｗｗ
WindowsでLambdaのGoバイナリをzip圧縮すると実行に失敗する

（Git Bash使用）
WindowsでLambda関数をGolangでコンパイル

```
GOOS=linux GOARCH=amd64 go build -o hello
```

これを、Windows標準機能でzip圧縮。
![1.png](https://qiita-image-store.s3.amazonaws.com/0/38162/d466696d-6ca3-19c5-7d21-6446065624b5.png)

これをLambdaでアップロードし、テスト実行したところ、
perrmission denied
となり、実行に失敗した。
![2.png](https://qiita-image-store.s3.amazonaws.com/0/38162/9a486328-c047-5eed-cb7e-4fb4046ce735.png)

WinRARでzip圧縮しても同様に失敗。

WSLやDockerコンテナのLinuxから

```
zip hello.zip ./hello
```

としたものは成功した。

Windows標準やWinRARのzip圧縮は、その過程で実行属性が取れてしまっているものと推測。
セキュアなSSHサーバの設定

# 概要

　前回の「[Amazon Linux 2のsshサーバをよりセキュアに！](https://qiita.com/comefigo/items/a2f408808e3801aa594e)」に続き、SSHサーバ全体の設定を残したいと思います

　以下の項目値がsshd_configに設定されていない場合はデフォルト値で動作するので、項目値を追加することで動作を制限することができます。なお、OpenSSHのバージョンによっては設定できないものもありますので、[マニュアル](https://man.openbsd.org/sshd_config)を確認してから設定してください
　また、設定したことによって、古いSSHクライアントが接続できなくなったり、SSHサーバに接続できなくなることもありますので、事前に確認してから設定を行ってください！

## プロトコルのバージョン（必須）

Protocol 1は中間者攻撃に問題があるため、Protocol 2を使用しましょう
OpenSSH 7.6以上はデフォルトで2になっています（[Protocol 1はサポートされていない](https://www.openssh.com/txt/release-7.6)）

```conf:/etc/ssh/sshd_config
Protocol 2
```

## パスワード認証を無効（必須）

どうしてもパスワード認証しなければならない場合は、安全なパスワードを設定してください
IPAの[チョコっとプラスパスワード](https://www.ipa.go.jp/chocotto/pw.html)や日本語パスワードなどが参考になります

```conf:/etc/ssh/sshd_config
PasswordAuthentication no
```

## チャレンジ/レスポンス認証を無効（必須）

[チャレンジ/レスポンス認証](http://e-words.jp/w/%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8-%E3%83%AC%E3%82%B9%E3%83%9D%E3%83%B3%E3%82%B9%E8%AA%8D%E8%A8%BC.html)

パスワード認証を安全に行えるようにするための仕組みですが、パスワード認証を無効にするのが前提なので、こちらも無効とする

```
ChallengeResponseAuthentication no
```

## 空パスワードを無効（必須）

開発中はいいが、本番環境はNG

```conf:/etc/ssh/sshd_config
PermitEmptyPasswords no
```

## rootユーザのログインを禁止（必須）

基本rootユーザで操作しないのが原則なので、rootユーザのログインから禁止

```conf:/etc/ssh/sshd_config
PermitRootLogin no
```

## ログレベル（必須）

ログインに関するログ(成功、失敗)が出力されるようにする
問題が発生した時に状況をトレースしやすくするため

```conf:/etc/ssh/sshd_config
SyslogFacility AUTHPRIV
LogLevel VERBOSE
```

※あわせて[rsyslogのログテンプレート](https://www.rsyslog.com/doc/v8-stable/configuration/templates.html)を設定しておくと情報が過不足にならずに済みます

## 接続できるユーザを制限する（任意）

```conf:/etc/ssh/sshd_config
AllowUsers work_user
```

## 特定のユーザからの接続を拒否する（任意）

AWS EC2のようにデフォルトユーザ（`ec2-user`）が知れ渡っているような場合は、
デフォルトユーザを削除したり、接続禁止設定しとくと安全でしょう

```conf:/etc/ssh/sshd_config
DenyUsers ec2-user
```

## SSH接続ポートの変更（任意）

デフォルト22番ポート以外の任意のポートに割り当てることで攻撃を遅らせることができます
**※割り当て予定のポートを事前にファイアウオールで許可するようにしてください！**

```conf:/etc/ssh/sshd_config
Port 1022
```

## SSHポートフォワードの禁止（任意）

SSH接続を経由して、他のサーバに転送通信（トンネリング）をできなくする

```conf:/etc/ssh/sshd_config
AllowTcpForwarding no
AllowStreamLocalForwarding no
GatewayPorts no
PermitTunnel no
```



# 参考

https://www.ssh.com/ssh/sshd_config/
Dockerチュートリアルやってみた

本格的にオリジナルWEBサービス作る前に、
ちょっと開発環境を整えようと思ったので。

なんだかみんな当たり前のようにDockerを使ってるので
ぼくも使い方を学んでおこうと思ったのです。

#Docker for mac のダウンロード

https://docs.docker.com/docker-for-mac/install/

ここにDMG形式で置いてあるので、インスコで迷うことはなかった。
Dockerにメアド登録が必要。メアドが必要だがクレカとかはいらない。

```
docker -v
```
バージョン確認できればおk。Kids stuff.


# Dockerチュートリアル

https://docs.docker.com/get-started/

英語だけど、読めなくはない。
翻訳したり、日本語で補足してるQiita記事とかもあるから
なんとかなりそう。

```
docker run hello-world
```

１文字も書いていないのにいきなりhello worldだ。
気が早いなdocker。

```
docker run 名前
```

で、該当する名前のコンテナ（？）を探して実行しようとする。
dockerはまずローカルを探す。
無ければライブラリ？から探してダウンロードして実行してくれるらしい。

なので、何も書いてないのに、ハロワることが可能になるっぽい。

あとは docker image とか docker container とか
今後、基本となってくるコマンドの使い方をさらっとやって１章終了。

さくさく進めたい。
React, Redux & Firebaseを使ってプロジェクトを作る

自分用メモ

## yarn download

```terminal
brew install yarn
```
*npmで以下の作業を行っても平気

## reactテンプレートのダウンロード

```terminal
yarn create-react-app my-app
```


## 必要なパッケージを入れる
### reduxのパッケージ
```terminal
yarn add redux react-redux redux-thunk
```
### reduxのパッケージ
```terminal
yarn add firebase
```
### react-redux-firebaseのパッケージ
```terminal
cd my-app
yarn add react-redux-firebase
```
### package.jsonにちゃんとインストールされているか確認する

```json:package.json
{
  "name": "test",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "firebase": "^5.2.0",
    "package.json": "^2.0.1",
    "react": "^16.4.1",
    "react-dom": "^16.4.1",
    "react-redux-firebase": "^2.1.6",
    "react-scripts": "1.1.4"
    "redux": "^4.0.0",
    "redux-thunk": "^2.3.0"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject"
  }
}
```
## json:package.jsonのインストール
``` terminal
yarn add package.json
```
## projectのスタート
```terminal
yarn start
```

## 参照
https://medium.com/quick-code/how-to-integrate-react-redux-and-firebase-in-3-simple-steps-c44804a6af38
Z39.50検索メモ(yaz-client)

# Z39.50について

- [Z39.50](https://ja.wikipedia.org/wiki/Z39.50)は主に図書館界で書誌データ検索用のプロトコルとして使われてきたもの。
- 国内外の国立図書館等の書誌検索サービスで利用されている。
- アメリカの議会図書館(Library of Congress:LC)が仕様を管理している([Z39.50 Maintenance Agency](http://www.loc.gov/z3950/agency/))。

# yaz-clientについて

- [YAZ](https://www.indexdata.com/resources/software/yaz/)はIndex Data社が提供するZ39.50対応toolkit。
- yaz-clientはYAZに含まれるZ39.50検索用コマンド。
- [yaz-client Reference](https://software.indexdata.com/yaz/doc/yaz-client.html)

# 対話的な使い方

- 以下では、アメリカ議会図書館のZ39.50サービスの利用を想定([LC Z39.50/SRW/SRU Server Configuration Guidelines](https://www.loc.gov/z3950/lcserver.html))。
- yaz-clientを起動するとプロンプトが表示される。

```
D:\> yaz-client
Z>
```

- サーバに接続する。

```
Z> open tcp:lx2.loc.gov:210
```

- データベースを選択する。

```
Z> base LCDB
```

- 出力フォーマットを選択する。

```
Z> format XML
```

- 出力ファイルを指定する。

```
Z> set_marcdump output.txt
```

- 検索を実行する。
- 検索式はPQF(Prefix Query Format)という書式を使う。
- 下の例で「7」が検索項目にあたる。LCの設定ガイドで[アトリビュート値](https://www.loc.gov/z3950/lcserver.html#usea)として掲載されている値。「7」はISBN。スペースのあとに検索語を書く。

```
Z> find @attr 1=7 1565921836
```

- 検索結果を表示する。

```
Z> show
```

- サーバから切断する。

```
Z> close
```

- 終了する。

```
Z> quit
```

# バッチ的な使い方

- 対話モードのコマンドをファイルに書いて-fオプションで指定するとバッチ的に実行できる。

```
D:\> yaz-client -f command.txt
```

- コマンドファイルは次のような内容。

```
open tcp:lx2.loc.gov:210
base LCDB
format XML
set_marcdump output.txt
find @attr 1=7 1565921836
show
close
quit
```